Files
marco/app/services/osm-auth.js
Râu Cao e7dfed204e
All checks were successful
CI / Lint (pull_request) Successful in 30s
CI / Test (pull_request) Successful in 49s
Release Drafter / Update release notes draft (pull_request) Successful in 4s
Connect OSM account
2026-04-01 18:46:19 +04:00

104 lines
2.8 KiB
JavaScript

import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { OAuth2AuthCodePkceClient } from 'oauth2-pkce';
class MarcoOsmAuthStorage {
saveState(serializedState) {
localStorage.setItem('marco:osm_auth_state', serializedState);
}
loadState() {
return localStorage.getItem('marco:osm_auth_state');
}
}
export default class OsmAuthService extends Service {
@tracked isConnected = false;
@tracked userDisplayName = null;
oauthClient;
constructor() {
super(...arguments);
const clientId =
import.meta.env.VITE_OSM_CLIENT_ID || 'YOUR_CLIENT_ID_HERE';
const oauthUrl =
import.meta.env.VITE_OSM_OAUTH_URL || 'https://www.openstreetmap.org';
const redirectUrl =
import.meta.env.VITE_OSM_REDIRECT_URI ||
`${window.location.origin}/oauth/osm/callback`;
this.oauthClient = new OAuth2AuthCodePkceClient(
{
scopes: ['read_prefs', 'write_api'],
authorizationUrl: `${oauthUrl}/oauth2/authorize`,
tokenUrl: `${oauthUrl}/oauth2/token`,
clientId: clientId,
redirectUrl: redirectUrl,
storeRefreshToken: true,
},
new MarcoOsmAuthStorage()
);
this.restoreSession();
}
async restoreSession() {
const isAuthorized = await this.oauthClient.isAuthorized();
if (isAuthorized) {
this.isConnected = true;
const storedName = localStorage.getItem('marco:osm_user_display_name');
if (storedName) {
this.userDisplayName = storedName;
} else {
await this.fetchUserInfo();
}
}
}
async login() {
await this.oauthClient.requestAuthorizationCode();
}
async handleCallback() {
await this.oauthClient.receiveCode();
await this.oauthClient.getTokens();
this.isConnected = true;
await this.fetchUserInfo();
}
async logout() {
await this.oauthClient.reset();
this.isConnected = false;
this.userDisplayName = null;
localStorage.removeItem('marco:osm_user_display_name');
}
async fetchUserInfo() {
try {
const tokens = await this.oauthClient.getTokens();
// eslint-disable-next-line warp-drive/no-external-request-patterns
const response = await fetch(
'https://api.openstreetmap.org/api/0.6/user/details.json',
{
headers: {
Authorization: `Bearer ${tokens.accessToken}`,
},
}
);
if (response.ok) {
const data = await response.json();
console.debug('OSM data:', data);
const displayName = data.user.display_name;
this.userDisplayName = displayName;
localStorage.setItem('marco:osm_user_display_name', displayName);
} else {
console.error('Failed to fetch OSM user info', response.status);
}
} catch (e) {
console.error('Error fetching OSM user info', e);
}
}
}