-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
auth.ts
88 lines (78 loc) · 2.51 KB
/
auth.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { HttpClient, OAuth2AuthCodePKCE } from '@bity/oauth2-auth-code-pkce';
import { readStream } from './ndJsonStream';
import { BASE_PATH } from './routing';
export const lichessHost = 'https://lichess.org';
// export const lichessHost = 'http://l.org';
export const scopes = ['board:play'];
export const clientId = 'lichess-api-demo';
export const clientUrl = `${location.protocol}//${location.host}${BASE_PATH || '/'}`;
export interface Me {
id: string;
username: string;
httpClient: HttpClient; // with pre-set Authorization header
perfs: { [key: string]: any };
}
export class Auth {
oauth = new OAuth2AuthCodePKCE({
authorizationUrl: `${lichessHost}/oauth`,
tokenUrl: `${lichessHost}/api/token`,
clientId,
scopes,
redirectUrl: clientUrl,
onAccessTokenExpiry: refreshAccessToken => refreshAccessToken(),
onInvalidGrant: console.warn,
});
me?: Me;
async init() {
try {
const accessContext = await this.oauth.getAccessToken();
if (accessContext) await this.authenticate();
} catch (err) {
console.error(err);
}
if (!this.me) {
try {
const hasAuthCode = await this.oauth.isReturningFromAuthServer();
if (hasAuthCode) await this.authenticate();
} catch (err) {
console.error(err);
}
}
}
async login() {
await this.oauth.fetchAuthorizationCode();
}
async logout() {
if (this.me) await this.me.httpClient(`${lichessHost}/api/token`, { method: 'DELETE' });
localStorage.clear();
this.me = undefined;
}
private authenticate = async () => {
const httpClient = this.oauth.decorateFetchHTTPClient(window.fetch);
const res = await httpClient(`${lichessHost}/api/account`);
const me = {
...(await res.json()),
httpClient,
};
if (me.error) throw me.error;
this.me = me;
};
openStream = async (path: string, config: any, handler: (_: any) => void) => {
const stream = await this.fetchResponse(path, config);
return readStream(`STREAM ${path}`, stream, handler);
};
fetchBody = async (path: string, config: any = {}) => {
const res = await this.fetchResponse(path, config);
const body = await res.json();
return body;
};
private fetchResponse = async (path: string, config: any = {}) => {
const res = await (this.me?.httpClient || window.fetch)(`${lichessHost}${path}`, config);
if (res.error || !res.ok) {
const err = `${res.error} ${res.status} ${res.statusText}`;
alert(err);
throw err;
}
return res;
};
}