diff --git a/src/Logic/Osm/OsmConnection.ts b/src/Logic/Osm/OsmConnection.ts index ecf29dcf2..21540e228 100644 --- a/src/Logic/Osm/OsmConnection.ts +++ b/src/Logic/Osm/OsmConnection.ts @@ -6,6 +6,7 @@ import { Utils } from "../../Utils" import { LocalStorageSource } from "../Web/LocalStorageSource" import { AuthConfig } from "./AuthConfig" import Constants from "../../Models/Constants" +import OSMAuthInstance = OSMAuth.OSMAuthInstance export default class UserDetails { public loggedIn = false @@ -29,7 +30,7 @@ export default class UserDetails { export type OsmServiceState = "online" | "readonly" | "offline" | "unknown" | "unreachable" export class OsmConnection { - public auth + public auth: OSMAuthInstance public userDetails: UIEventSource public isLoggedIn: Store public gpxServiceIsOnline: UIEventSource = new UIEventSource( @@ -118,17 +119,16 @@ export class OsmConnection { const self = this this.auth.bootstrapToken( options.oauth_token.data, - (x) => { - console.log("Called back: ", x) + (err, result) => { + console.log("Bootstrap token called back", err, result) self.AttemptLogin() - }, - this.auth + } ) options.oauth_token.setData(undefined) } if (this.auth.authenticated() && options.attemptLogin !== false) { - this.AttemptLogin() // Also updates the user badge + this.AttemptLogin() } else { console.log("Not authenticated") } @@ -263,17 +263,33 @@ export class OsmConnection { /** * Interact with the API. * - * @param path: the path to query, without host and without '/api/0.6'. Example 'notes/1234/close' + * @param path the path to query, without host and without '/api/0.6'. Example 'notes/1234/close' + * @param method + * @param header + * @param content + * @param allowAnonymous if set, will use the anonymous-connection if the main connection is not authenticated */ public async interact( path: string, method: "GET" | "POST" | "PUT" | "DELETE", header?: Record, - content?: string - ): Promise { + content?: string, + allowAnonymous: boolean = false + ): Promise { + + let connection: OSMAuthInstance = this.auth + if(allowAnonymous && !this.auth.authenticated()) { + const possibleResult = await Utils.downloadAdvanced(`${this.Backend()}/api/0.6/${path}`,header, method, content) + if(possibleResult["content"]) { + return possibleResult["content"] + } + console.error(possibleResult) + throw "Could not interact with OSM:"+possibleResult["error"] + } + return new Promise((ok, error) => { - this.auth.xhr( - { + connection.xhr( + { method, options: { header, @@ -295,9 +311,10 @@ export class OsmConnection { public async post( path: string, content?: string, - header?: Record + header?: Record, + allowAnonymous: boolean = false ): Promise { - return await this.interact(path, "POST", header, content) + return await this.interact(path, "POST", header, content, allowAnonymous) } public async put( @@ -353,9 +370,10 @@ export class OsmConnection { // Lat and lon must be strings for the API to accept it const content = `lat=${lat}&lon=${lon}&text=${encodeURIComponent(text)}` const response = await this.post("notes.json", content, { - "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", - }) + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, true) const parsed = JSON.parse(response) + console.log("Got result:", parsed) const id = parsed.properties console.log("OPENED NOTE", id) return id @@ -489,13 +507,14 @@ export class OsmConnection { this.auth = new osmAuth({ client_id: this._oauth_config.oauth_client_id, url: this._oauth_config.url, - scope: "read_prefs write_prefs write_api write_gpx write_notes", + scope: "read_prefs write_prefs write_api write_gpx write_notes openid", redirect_uri: Utils.runningFromConsole ? "https://mapcomplete.org/land.html" : window.location.protocol + "//" + window.location.host + "/land.html", singlepage: !standalone, auto: true, }) + } private CheckForMessagesContinuously() { diff --git a/src/Utils.ts b/src/Utils.ts index 180c727cb..26d4bca8b 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -972,7 +972,9 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be */ public static downloadAdvanced( url: string, - headers?: any + headers?: any, + method: "POST" | "GET" | "PUT" | "UPDATE" | "DELETE" | "OPTIONS" = "GET", + content?: string ): Promise< | { content: string } | { redirect: string } @@ -999,14 +1001,13 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be }) } } - xhr.open("GET", url) + xhr.open(method, url) if (headers !== undefined) { for (const key in headers) { xhr.setRequestHeader(key, headers[key]) } } - - xhr.send() + xhr.send(content) xhr.onerror = reject }) }