@rool-dev/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1070 -0
- package/dist/apps.d.ts +29 -0
- package/dist/apps.d.ts.map +1 -0
- package/dist/apps.js +88 -0
- package/dist/apps.js.map +1 -0
- package/dist/auth-browser.d.ts +80 -0
- package/dist/auth-browser.d.ts.map +1 -0
- package/dist/auth-browser.js +370 -0
- package/dist/auth-browser.js.map +1 -0
- package/dist/auth-node.d.ts +46 -0
- package/dist/auth-node.d.ts.map +1 -0
- package/dist/auth-node.js +316 -0
- package/dist/auth-node.js.map +1 -0
- package/dist/auth.d.ts +56 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +96 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +202 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +472 -0
- package/dist/client.js.map +1 -0
- package/dist/event-emitter.d.ts +38 -0
- package/dist/event-emitter.d.ts.map +1 -0
- package/dist/event-emitter.js +80 -0
- package/dist/event-emitter.js.map +1 -0
- package/dist/graphql.d.ts +71 -0
- package/dist/graphql.d.ts.map +1 -0
- package/dist/graphql.js +487 -0
- package/dist/graphql.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonld.d.ts +47 -0
- package/dist/jsonld.d.ts.map +1 -0
- package/dist/jsonld.js +137 -0
- package/dist/jsonld.js.map +1 -0
- package/dist/media.d.ts +52 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +173 -0
- package/dist/media.js.map +1 -0
- package/dist/space.d.ts +358 -0
- package/dist/space.d.ts.map +1 -0
- package/dist/space.js +1121 -0
- package/dist/space.js.map +1 -0
- package/dist/subscription.d.ts +57 -0
- package/dist/subscription.d.ts.map +1 -0
- package/dist/subscription.js +296 -0
- package/dist/subscription.js.map +1 -0
- package/dist/types.d.ts +409 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +65 -0
package/dist/apps.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PublishedAppInfo, PublishAppOptions } from './types.js';
|
|
2
|
+
import type { AuthManager } from './auth.js';
|
|
3
|
+
export interface AppsClientConfig {
|
|
4
|
+
appsUrl: string;
|
|
5
|
+
authManager: AuthManager;
|
|
6
|
+
}
|
|
7
|
+
export declare class AppsClient {
|
|
8
|
+
private config;
|
|
9
|
+
constructor(config: AppsClientConfig);
|
|
10
|
+
/**
|
|
11
|
+
* List all published apps for the current user.
|
|
12
|
+
*/
|
|
13
|
+
list(): Promise<PublishedAppInfo[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Get info for a specific published app.
|
|
16
|
+
*/
|
|
17
|
+
get(appId: string): Promise<PublishedAppInfo | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Publish or update an app.
|
|
20
|
+
* @param appId - URL-safe identifier for the app
|
|
21
|
+
* @param options - App name, bundle (zip file), and optional SPA flag
|
|
22
|
+
*/
|
|
23
|
+
publish(appId: string, options: PublishAppOptions): Promise<PublishedAppInfo>;
|
|
24
|
+
/**
|
|
25
|
+
* Unpublish an app.
|
|
26
|
+
*/
|
|
27
|
+
unpublish(appId: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=apps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,EAAE,gBAAgB;IAIpC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgBzC;;OAEG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAoB1D;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0BnF;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAa9C"}
|
package/dist/apps.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Apps Client
|
|
3
|
+
// REST API wrapper for app publishing/unpublishing/listing
|
|
4
|
+
// =============================================================================
|
|
5
|
+
export class AppsClient {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* List all published apps for the current user.
|
|
12
|
+
*/
|
|
13
|
+
async list() {
|
|
14
|
+
const token = await this.config.authManager.getToken();
|
|
15
|
+
if (!token)
|
|
16
|
+
throw new Error('Not authenticated');
|
|
17
|
+
const response = await fetch(this.config.appsUrl, {
|
|
18
|
+
method: 'GET',
|
|
19
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
20
|
+
});
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
throw new Error(`Failed to list apps: ${response.status} ${response.statusText}`);
|
|
23
|
+
}
|
|
24
|
+
return response.json();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get info for a specific published app.
|
|
28
|
+
*/
|
|
29
|
+
async get(appId) {
|
|
30
|
+
const token = await this.config.authManager.getToken();
|
|
31
|
+
if (!token)
|
|
32
|
+
throw new Error('Not authenticated');
|
|
33
|
+
const response = await fetch(`${this.config.appsUrl}/${encodeURIComponent(appId)}`, {
|
|
34
|
+
method: 'GET',
|
|
35
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
36
|
+
});
|
|
37
|
+
if (response.status === 404) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
throw new Error(`Failed to get app: ${response.status} ${response.statusText}`);
|
|
42
|
+
}
|
|
43
|
+
return response.json();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Publish or update an app.
|
|
47
|
+
* @param appId - URL-safe identifier for the app
|
|
48
|
+
* @param options - App name, bundle (zip file), and optional SPA flag
|
|
49
|
+
*/
|
|
50
|
+
async publish(appId, options) {
|
|
51
|
+
const token = await this.config.authManager.getToken();
|
|
52
|
+
if (!token)
|
|
53
|
+
throw new Error('Not authenticated');
|
|
54
|
+
const formData = new FormData();
|
|
55
|
+
formData.append('bundle', options.bundle);
|
|
56
|
+
formData.append('name', options.name);
|
|
57
|
+
if (options.spa !== undefined) {
|
|
58
|
+
formData.append('spa', String(options.spa));
|
|
59
|
+
}
|
|
60
|
+
const response = await fetch(`${this.config.appsUrl}/${encodeURIComponent(appId)}`, {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
63
|
+
body: formData,
|
|
64
|
+
});
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
const errorBody = await response.json().catch(() => ({}));
|
|
67
|
+
const errorMessage = errorBody.error || `${response.status} ${response.statusText}`;
|
|
68
|
+
throw new Error(`Failed to publish app: ${errorMessage}`);
|
|
69
|
+
}
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Unpublish an app.
|
|
74
|
+
*/
|
|
75
|
+
async unpublish(appId) {
|
|
76
|
+
const token = await this.config.authManager.getToken();
|
|
77
|
+
if (!token)
|
|
78
|
+
throw new Error('Not authenticated');
|
|
79
|
+
const response = await fetch(`${this.config.appsUrl}/${encodeURIComponent(appId)}`, {
|
|
80
|
+
method: 'DELETE',
|
|
81
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok && response.status !== 204) {
|
|
84
|
+
throw new Error(`Failed to unpublish app: ${response.status} ${response.statusText}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=apps.js.map
|
package/dist/apps.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { AuthProvider, AuthUser } from './types.js';
|
|
2
|
+
export interface BrowserAuthConfig {
|
|
3
|
+
/** Auth service URL (e.g. https://api.dev.rool.dev/auth) */
|
|
4
|
+
authUrl: string;
|
|
5
|
+
storagePrefix?: string;
|
|
6
|
+
onAuthStateChanged: (authenticated: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare class BrowserAuthProvider implements AuthProvider {
|
|
9
|
+
private config;
|
|
10
|
+
private apiKey;
|
|
11
|
+
private apiKeyFetchPromise;
|
|
12
|
+
private refreshPromise;
|
|
13
|
+
private refreshTimeoutId;
|
|
14
|
+
private get storageKeys();
|
|
15
|
+
/** Auth URL without trailing slash */
|
|
16
|
+
private get authBaseUrl();
|
|
17
|
+
constructor(config: BrowserAuthConfig);
|
|
18
|
+
/**
|
|
19
|
+
* Initialize auth manager - should be called on app startup.
|
|
20
|
+
* Processes any auth callback in the URL and sets up auto-refresh.
|
|
21
|
+
*/
|
|
22
|
+
initialize(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check if user is currently authenticated (validates token is usable).
|
|
25
|
+
*/
|
|
26
|
+
isAuthenticated(): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Get current access token, refreshing if expired.
|
|
29
|
+
* Returns undefined if not authenticated.
|
|
30
|
+
*/
|
|
31
|
+
getToken(): Promise<string | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* Get auth identity decoded from JWT token.
|
|
34
|
+
*/
|
|
35
|
+
getAuthUser(): AuthUser;
|
|
36
|
+
/**
|
|
37
|
+
* Initiate login by redirecting to auth page.
|
|
38
|
+
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
39
|
+
*/
|
|
40
|
+
login(appName: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Logout - clear all tokens and state.
|
|
43
|
+
*/
|
|
44
|
+
logout(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Process auth callback from URL fragment.
|
|
47
|
+
* Should be called on page load.
|
|
48
|
+
* @returns true if callback was processed
|
|
49
|
+
*/
|
|
50
|
+
processCallback(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Destroy auth manager - clear refresh timers.
|
|
53
|
+
*/
|
|
54
|
+
destroy(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get cached storage data from localStorage.
|
|
57
|
+
*/
|
|
58
|
+
getStorage(): Record<string, unknown> | null;
|
|
59
|
+
/**
|
|
60
|
+
* Set cached storage data to localStorage.
|
|
61
|
+
*/
|
|
62
|
+
setStorage(data: Record<string, unknown>): void;
|
|
63
|
+
/**
|
|
64
|
+
* Get the API key, fetching from server if not provided in config.
|
|
65
|
+
*/
|
|
66
|
+
private getApiKey;
|
|
67
|
+
private tryRefreshToken;
|
|
68
|
+
private scheduleTokenRefresh;
|
|
69
|
+
private cancelScheduledRefresh;
|
|
70
|
+
private readAccessToken;
|
|
71
|
+
private readExpiresAt;
|
|
72
|
+
private writeTokens;
|
|
73
|
+
private clearTokens;
|
|
74
|
+
private storeState;
|
|
75
|
+
private readState;
|
|
76
|
+
private clearState;
|
|
77
|
+
private generateState;
|
|
78
|
+
private decodeAuthUser;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=auth-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-browser.d.ts","sourceRoot":"","sources":["../src/auth-browser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAOzD,MAAM,WAAW,iBAAiB;IAC9B,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;CACxD;AAED,qBAAa,mBAAoB,YAAW,YAAY;IACpD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,gBAAgB,CAA8C;IAEtE,OAAO,KAAK,WAAW,GAQtB;IAED,sCAAsC;IACtC,OAAO,KAAK,WAAW,GAEtB;gBAEW,MAAM,EAAE,iBAAiB;IAIrC;;;OAGG;IACH,UAAU,IAAI,OAAO;IAMrB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAKzC;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAgB7C;;OAEG;IACH,WAAW,IAAI,QAAQ;IAMvB;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAa5B;;OAEG;IACH,MAAM,IAAI,IAAI;IAOd;;;;OAIG;IACH,eAAe,IAAI,OAAO;IAyC1B;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAU5C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAa/C;;OAEG;YACW,SAAS;YAgCT,eAAe;IA4E7B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,WAAW;IAwBnB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,cAAc;CAYzB"}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
const GCIP_REFRESH_ENDPOINT = 'https://securetoken.googleapis.com/v1/token';
|
|
2
|
+
const REFRESH_BUFFER_MS = 5 * 60 * 1000; // Refresh 5 minutes before expiry
|
|
3
|
+
const DEFAULT_STORAGE_PREFIX = 'rool_';
|
|
4
|
+
export class BrowserAuthProvider {
|
|
5
|
+
config;
|
|
6
|
+
apiKey = null;
|
|
7
|
+
apiKeyFetchPromise = null;
|
|
8
|
+
refreshPromise = null;
|
|
9
|
+
refreshTimeoutId = null;
|
|
10
|
+
get storageKeys() {
|
|
11
|
+
const prefix = this.config.storagePrefix ?? DEFAULT_STORAGE_PREFIX;
|
|
12
|
+
return {
|
|
13
|
+
access: `${prefix}access_token`,
|
|
14
|
+
refresh: `${prefix}refresh_token`,
|
|
15
|
+
expiresAt: `${prefix}token_expires_at`,
|
|
16
|
+
state: `${prefix}auth_state`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Auth URL without trailing slash */
|
|
20
|
+
get authBaseUrl() {
|
|
21
|
+
return this.config.authUrl.replace(/\/+$/, '');
|
|
22
|
+
}
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Initialize auth manager - should be called on app startup.
|
|
28
|
+
* Processes any auth callback in the URL and sets up auto-refresh.
|
|
29
|
+
*/
|
|
30
|
+
initialize() {
|
|
31
|
+
const wasCallback = this.processCallback();
|
|
32
|
+
this.scheduleTokenRefresh();
|
|
33
|
+
return wasCallback;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if user is currently authenticated (validates token is usable).
|
|
37
|
+
*/
|
|
38
|
+
async isAuthenticated() {
|
|
39
|
+
const token = await this.getToken();
|
|
40
|
+
return token !== undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get current access token, refreshing if expired.
|
|
44
|
+
* Returns undefined if not authenticated.
|
|
45
|
+
*/
|
|
46
|
+
async getToken() {
|
|
47
|
+
const accessToken = this.readAccessToken();
|
|
48
|
+
const expiresAt = this.readExpiresAt();
|
|
49
|
+
if (!accessToken)
|
|
50
|
+
return undefined;
|
|
51
|
+
// Token expired or about to expire - try refresh
|
|
52
|
+
if (expiresAt && Date.now() >= expiresAt - REFRESH_BUFFER_MS) {
|
|
53
|
+
const refreshed = await this.tryRefreshToken();
|
|
54
|
+
if (!refreshed)
|
|
55
|
+
return undefined;
|
|
56
|
+
return this.readAccessToken() ?? undefined;
|
|
57
|
+
}
|
|
58
|
+
return accessToken;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get auth identity decoded from JWT token.
|
|
62
|
+
*/
|
|
63
|
+
getAuthUser() {
|
|
64
|
+
const accessToken = this.readAccessToken();
|
|
65
|
+
if (!accessToken)
|
|
66
|
+
return { email: null, name: null };
|
|
67
|
+
return this.decodeAuthUser(accessToken);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Initiate login by redirecting to auth page.
|
|
71
|
+
* @param appName - The name of the application requesting login (displayed on auth page)
|
|
72
|
+
*/
|
|
73
|
+
login(appName) {
|
|
74
|
+
const loginUrl = new URL(`${this.authBaseUrl}/`);
|
|
75
|
+
const redirectTarget = window.location.origin + window.location.pathname + window.location.search;
|
|
76
|
+
loginUrl.searchParams.set('redirect_uri', redirectTarget);
|
|
77
|
+
loginUrl.searchParams.set('app_name', appName);
|
|
78
|
+
const state = this.generateState();
|
|
79
|
+
this.storeState(state);
|
|
80
|
+
loginUrl.searchParams.set('state', state);
|
|
81
|
+
window.location.href = loginUrl.toString();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Logout - clear all tokens and state.
|
|
85
|
+
*/
|
|
86
|
+
logout() {
|
|
87
|
+
this.clearTokens();
|
|
88
|
+
this.clearState();
|
|
89
|
+
this.cancelScheduledRefresh();
|
|
90
|
+
this.config.onAuthStateChanged(false);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Process auth callback from URL fragment.
|
|
94
|
+
* Should be called on page load.
|
|
95
|
+
* @returns true if callback was processed
|
|
96
|
+
*/
|
|
97
|
+
processCallback() {
|
|
98
|
+
const hash = window.location.hash ?? '';
|
|
99
|
+
const trimmed = hash.startsWith('#') ? hash.slice(1) : hash;
|
|
100
|
+
if (!trimmed)
|
|
101
|
+
return false;
|
|
102
|
+
const params = new URLSearchParams(trimmed);
|
|
103
|
+
const idToken = params.get('id_token');
|
|
104
|
+
if (!idToken)
|
|
105
|
+
return false;
|
|
106
|
+
const refreshToken = params.get('refresh_token');
|
|
107
|
+
const expiresIn = params.get('expires_in');
|
|
108
|
+
const expiresAt = expiresIn ? Date.now() + Number(expiresIn) * 1000 : NaN;
|
|
109
|
+
const incomingState = params.get('state');
|
|
110
|
+
const storedState = this.readState();
|
|
111
|
+
// Validate state - if we stored one, require it back
|
|
112
|
+
if (storedState && incomingState !== storedState) {
|
|
113
|
+
console.error('[RoolClient] Auth state mismatch. Token fragment ignored.');
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
if (!Number.isFinite(expiresAt)) {
|
|
117
|
+
console.error('[RoolClient] Auth response missing expires_in. Token ignored.');
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
// Clear state and store tokens
|
|
121
|
+
this.clearState();
|
|
122
|
+
this.writeTokens(idToken, refreshToken, expiresAt);
|
|
123
|
+
// Clean URL
|
|
124
|
+
const cleanUrl = window.location.origin + window.location.pathname + window.location.search;
|
|
125
|
+
window.history.replaceState({}, document.title, cleanUrl);
|
|
126
|
+
// Schedule refresh and notify
|
|
127
|
+
this.scheduleTokenRefresh();
|
|
128
|
+
this.config.onAuthStateChanged(true);
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Destroy auth manager - clear refresh timers.
|
|
133
|
+
*/
|
|
134
|
+
destroy() {
|
|
135
|
+
this.cancelScheduledRefresh();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get cached storage data from localStorage.
|
|
139
|
+
*/
|
|
140
|
+
getStorage() {
|
|
141
|
+
try {
|
|
142
|
+
const key = `${this.config.storagePrefix ?? DEFAULT_STORAGE_PREFIX}user_storage`;
|
|
143
|
+
const data = localStorage.getItem(key);
|
|
144
|
+
return data ? JSON.parse(data) : null;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Set cached storage data to localStorage.
|
|
152
|
+
*/
|
|
153
|
+
setStorage(data) {
|
|
154
|
+
try {
|
|
155
|
+
const key = `${this.config.storagePrefix ?? DEFAULT_STORAGE_PREFIX}user_storage`;
|
|
156
|
+
localStorage.setItem(key, JSON.stringify(data));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Ignore localStorage errors
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ===========================================================================
|
|
163
|
+
// Private methods
|
|
164
|
+
// ===========================================================================
|
|
165
|
+
/**
|
|
166
|
+
* Get the API key, fetching from server if not provided in config.
|
|
167
|
+
*/
|
|
168
|
+
async getApiKey() {
|
|
169
|
+
// Already have it
|
|
170
|
+
if (this.apiKey)
|
|
171
|
+
return this.apiKey;
|
|
172
|
+
// Already fetching
|
|
173
|
+
if (this.apiKeyFetchPromise)
|
|
174
|
+
return this.apiKeyFetchPromise;
|
|
175
|
+
// Fetch from server
|
|
176
|
+
this.apiKeyFetchPromise = fetch(`${this.authBaseUrl}/config.json`)
|
|
177
|
+
.then(async (response) => {
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
console.warn('[RoolClient] Failed to fetch API key from server');
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
const data = await response.json();
|
|
183
|
+
if (data.apiKey && typeof data.apiKey === 'string') {
|
|
184
|
+
this.apiKey = data.apiKey;
|
|
185
|
+
return this.apiKey;
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
})
|
|
189
|
+
.catch((error) => {
|
|
190
|
+
console.warn('[RoolClient] Failed to fetch API key:', error);
|
|
191
|
+
return null;
|
|
192
|
+
})
|
|
193
|
+
.finally(() => {
|
|
194
|
+
this.apiKeyFetchPromise = null;
|
|
195
|
+
});
|
|
196
|
+
return this.apiKeyFetchPromise;
|
|
197
|
+
}
|
|
198
|
+
async tryRefreshToken() {
|
|
199
|
+
// Deduplicate concurrent refresh attempts
|
|
200
|
+
if (this.refreshPromise) {
|
|
201
|
+
return this.refreshPromise;
|
|
202
|
+
}
|
|
203
|
+
const refreshToken = localStorage.getItem(this.storageKeys.refresh);
|
|
204
|
+
if (!refreshToken)
|
|
205
|
+
return false;
|
|
206
|
+
// Get API key (from config or server)
|
|
207
|
+
const apiKey = await this.getApiKey();
|
|
208
|
+
if (!apiKey) {
|
|
209
|
+
console.warn('[RoolClient] Cannot refresh token: no API key available');
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const refreshUrl = new URL(GCIP_REFRESH_ENDPOINT);
|
|
213
|
+
refreshUrl.searchParams.set('key', apiKey);
|
|
214
|
+
this.refreshPromise = (async () => {
|
|
215
|
+
let response;
|
|
216
|
+
try {
|
|
217
|
+
response = await fetch(refreshUrl.toString(), {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
220
|
+
body: new URLSearchParams({
|
|
221
|
+
grant_type: 'refresh_token',
|
|
222
|
+
refresh_token: refreshToken,
|
|
223
|
+
}),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
// Network error - don't clear tokens, might work next time
|
|
228
|
+
console.warn('[RoolClient] Token refresh network error:', error);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
// 400/401 = refresh token is invalid, clear everything
|
|
232
|
+
if (response.status === 400 || response.status === 401) {
|
|
233
|
+
console.warn('[RoolClient] Refresh token invalid, clearing credentials');
|
|
234
|
+
this.clearTokens();
|
|
235
|
+
this.config.onAuthStateChanged(false);
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
// Other HTTP errors - don't clear tokens, might be transient
|
|
239
|
+
if (!response.ok) {
|
|
240
|
+
console.warn(`[RoolClient] Token refresh failed: ${response.status} ${response.statusText}`);
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
// Success - parse and store new tokens
|
|
244
|
+
try {
|
|
245
|
+
const data = await response.json();
|
|
246
|
+
const accessToken = data.id_token ?? data.access_token ?? null;
|
|
247
|
+
const nextRefreshToken = data.refresh_token ?? refreshToken;
|
|
248
|
+
const expiresAt = data.expires_in ? Date.now() + data.expires_in * 1000 : NaN;
|
|
249
|
+
if (!accessToken || !Number.isFinite(expiresAt)) {
|
|
250
|
+
console.error('[RoolClient] Refresh response missing access token or expires_in');
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
this.writeTokens(accessToken, nextRefreshToken, expiresAt);
|
|
254
|
+
this.scheduleTokenRefresh();
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error('[RoolClient] Failed to parse refresh response:', error);
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
})().finally(() => {
|
|
262
|
+
this.refreshPromise = null;
|
|
263
|
+
});
|
|
264
|
+
return this.refreshPromise;
|
|
265
|
+
}
|
|
266
|
+
scheduleTokenRefresh() {
|
|
267
|
+
this.cancelScheduledRefresh();
|
|
268
|
+
const expiresAt = this.readExpiresAt();
|
|
269
|
+
if (!expiresAt)
|
|
270
|
+
return;
|
|
271
|
+
const refreshAt = expiresAt - REFRESH_BUFFER_MS;
|
|
272
|
+
const delay = refreshAt - Date.now();
|
|
273
|
+
if (delay <= 0) {
|
|
274
|
+
// Already needs refresh
|
|
275
|
+
void this.tryRefreshToken();
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.refreshTimeoutId = setTimeout(() => {
|
|
279
|
+
void this.tryRefreshToken();
|
|
280
|
+
}, delay);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
cancelScheduledRefresh() {
|
|
284
|
+
if (this.refreshTimeoutId !== null) {
|
|
285
|
+
clearTimeout(this.refreshTimeoutId);
|
|
286
|
+
this.refreshTimeoutId = null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
readAccessToken() {
|
|
290
|
+
return localStorage.getItem(this.storageKeys.access);
|
|
291
|
+
}
|
|
292
|
+
readExpiresAt() {
|
|
293
|
+
const raw = localStorage.getItem(this.storageKeys.expiresAt);
|
|
294
|
+
if (!raw)
|
|
295
|
+
return null;
|
|
296
|
+
const parsed = Number.parseInt(raw, 10);
|
|
297
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
298
|
+
}
|
|
299
|
+
writeTokens(accessToken, refreshToken, expiresAt) {
|
|
300
|
+
if (accessToken) {
|
|
301
|
+
localStorage.setItem(this.storageKeys.access, accessToken);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
localStorage.removeItem(this.storageKeys.access);
|
|
305
|
+
}
|
|
306
|
+
if (refreshToken) {
|
|
307
|
+
localStorage.setItem(this.storageKeys.refresh, refreshToken);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
localStorage.removeItem(this.storageKeys.refresh);
|
|
311
|
+
}
|
|
312
|
+
if (expiresAt !== null && Number.isFinite(expiresAt)) {
|
|
313
|
+
localStorage.setItem(this.storageKeys.expiresAt, Math.floor(expiresAt).toString());
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
localStorage.removeItem(this.storageKeys.expiresAt);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
clearTokens() {
|
|
320
|
+
this.writeTokens(null, null, null);
|
|
321
|
+
}
|
|
322
|
+
storeState(value) {
|
|
323
|
+
try {
|
|
324
|
+
sessionStorage.setItem(this.storageKeys.state, value);
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
// Ignore storage restrictions
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
readState() {
|
|
331
|
+
try {
|
|
332
|
+
return sessionStorage.getItem(this.storageKeys.state);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
clearState() {
|
|
339
|
+
try {
|
|
340
|
+
sessionStorage.removeItem(this.storageKeys.state);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
// Ignore storage restrictions
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
generateState() {
|
|
347
|
+
try {
|
|
348
|
+
const buffer = new Uint8Array(16);
|
|
349
|
+
window.crypto.getRandomValues(buffer);
|
|
350
|
+
return Array.from(buffer, (value) => value.toString(16).padStart(2, '0')).join('');
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
decodeAuthUser(accessToken) {
|
|
357
|
+
try {
|
|
358
|
+
const payload = JSON.parse(atob(accessToken.split('.')[1]));
|
|
359
|
+
return {
|
|
360
|
+
email: payload.email || null,
|
|
361
|
+
name: payload.name || null,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
console.error('[RoolClient] Failed to decode token:', error);
|
|
366
|
+
return { email: null, name: null };
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=auth-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-browser.js","sourceRoot":"","sources":["../src/auth-browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AuthProvider, AuthUser } from './types.js';
|
|
2
|
+
export interface NodeAuthConfig {
|
|
3
|
+
/** Path to store credentials (default: ~/.config/rool/credentials.json) */
|
|
4
|
+
credentialsPath?: string;
|
|
5
|
+
/** Timeout for login flow in ms (default: 5 minutes) */
|
|
6
|
+
loginTimeoutMs?: number;
|
|
7
|
+
onAuthStateChanged?: (authenticated: boolean) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare class NodeAuthProvider implements AuthProvider {
|
|
10
|
+
private config;
|
|
11
|
+
private apiKey;
|
|
12
|
+
private _authUrl;
|
|
13
|
+
constructor(config?: NodeAuthConfig);
|
|
14
|
+
/** Called by AuthManager to inject the auth URL */
|
|
15
|
+
setAuthUrl(url: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Get a short hash of the auth URL for scoping credentials by endpoint.
|
|
18
|
+
*/
|
|
19
|
+
private get endpointHash();
|
|
20
|
+
private get credentialsPath();
|
|
21
|
+
/**
|
|
22
|
+
* Get the auth endpoint URL (without trailing slash).
|
|
23
|
+
*/
|
|
24
|
+
private get authEndpoint();
|
|
25
|
+
initialize(): boolean;
|
|
26
|
+
getToken(): Promise<string | undefined>;
|
|
27
|
+
getAuthUser(): AuthUser;
|
|
28
|
+
isAuthenticated(): Promise<boolean>;
|
|
29
|
+
login(appName: string): Promise<void>;
|
|
30
|
+
logout(): void;
|
|
31
|
+
private get storagePath();
|
|
32
|
+
/**
|
|
33
|
+
* Get cached storage data from filesystem.
|
|
34
|
+
*/
|
|
35
|
+
getStorage(): Record<string, unknown> | null;
|
|
36
|
+
/**
|
|
37
|
+
* Set cached storage data to filesystem.
|
|
38
|
+
*/
|
|
39
|
+
setStorage(data: Record<string, unknown>): void;
|
|
40
|
+
private readCredentials;
|
|
41
|
+
private writeCredentials;
|
|
42
|
+
private getApiKey;
|
|
43
|
+
private refreshToken;
|
|
44
|
+
private startLoopbackServer;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=auth-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-node.d.ts","sourceRoot":"","sources":["../src/auth-node.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAIzD,MAAM,WAAW,cAAc;IAC3B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;CACzD;AAQD,qBAAa,gBAAiB,YAAW,YAAY;IACjD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,MAAM,GAAE,cAAmB;IAIvC,mDAAmD;IACnD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B;;OAEG;IACH,OAAO,KAAK,YAAY,GAKvB;IAED,OAAO,KAAK,eAAe,GAQ1B;IAED;;OAEG;IACH,OAAO,KAAK,YAAY,GAKvB;IAED,UAAU,IAAI,OAAO;IAMf,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAY7C,WAAW,IAAI,QAAQ;IAejB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAKnC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+C3C,MAAM,IAAI,IAAI;IAQd,OAAO,KAAK,WAAW,GAItB;IAED;;OAEG;IACH,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAW5C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAe/C,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,gBAAgB;YAYV,SAAS;YAcT,YAAY;IAoD1B,OAAO,CAAC,mBAAmB;CAuE9B"}
|