blob: 02a790d576dc33b849c88b1109454c1e3daaf1a1 [file] [log] [blame]
Philipp Schraderad2a6fb2024-03-20 20:51:36 -07001import {Injectable} from '@angular/core';
2
3const AUTHORIZATION_URL = '/authorize';
4const AUTHORIZATION_CHECK_INTERVAL = 500; // ms
5const AUTHORIZATION_CHECK_DURATION = 20000; // ms
6const AUTHORIZATION_CHECK_ATTEMPTS =
7 AUTHORIZATION_CHECK_DURATION / AUTHORIZATION_CHECK_INTERVAL;
8
9@Injectable({providedIn: 'root'})
10export class RequestAuthorizer {
11 // Submits the buffer to the specified end point.
12 async submit(path: string, actionBuffer: Uint8Array): Promise<Response> {
13 const result = await this.singleSubmit(path, actionBuffer);
14 if (result.status === 401) {
15 await this.authorize();
16 return await this.singleSubmit(path, actionBuffer);
17 } else {
18 return result;
19 }
20 }
21
22 // Actually performs the underlying submission.
23 private async singleSubmit(
24 path: string,
25 actionBuffer: Uint8Array
26 ): Promise<Response> {
27 return await fetch(path, {
28 method: 'POST',
29 body: actionBuffer,
30 });
31 }
32
33 // Open a new tab in an attempt to re-authorize the user with the server.
34 private async authorize() {
35 const authorizationWindow = window.open(AUTHORIZATION_URL);
36 // We should deal with errors opening the tab, but this is good enough for now.
37
38 const tabIsClosed = new Promise<void>((resolve, reject) => {
39 let checkCounter = 0;
40 const tabCheckTimer = setInterval(() => {
41 if (authorizationWindow.closed) {
42 clearInterval(tabCheckTimer);
43 resolve();
44 }
45 checkCounter++;
46 if (checkCounter >= AUTHORIZATION_CHECK_ATTEMPTS) {
47 clearInterval(tabCheckTimer);
48 reject();
49 }
50 }, 500);
51 });
52 await tabIsClosed;
53 }
54}