@oxyhq/core 6.0.0 → 7.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/HttpService.js +1 -1
- package/dist/cjs/index.js +32 -11
- package/dist/cjs/mixins/OxyServices.accounts.js +7 -13
- package/dist/cjs/mixins/index.js +0 -5
- package/dist/cjs/server/index.js +2 -2
- package/dist/cjs/session/SessionClient.js +181 -10
- package/dist/cjs/session/accountDialogController.js +541 -0
- package/dist/cjs/session/accountProjection.js +131 -0
- package/dist/cjs/session/createSessionClient.js +9 -2
- package/dist/cjs/shared/utils/debugUtils.js +3 -3
- package/dist/cjs/utils/authWebUrl.js +10 -30
- package/dist/cjs/utils/coldBoot.js +10 -8
- package/dist/cjs/utils/{fapiAutoDetect.js → registrableApex.js} +8 -10
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/HttpService.js +1 -1
- package/dist/esm/index.js +26 -8
- package/dist/esm/mixins/OxyServices.accounts.js +7 -13
- package/dist/esm/mixins/index.js +0 -5
- package/dist/esm/server/index.js +1 -1
- package/dist/esm/session/SessionClient.js +181 -10
- package/dist/esm/session/accountDialogController.js +536 -0
- package/dist/esm/session/accountProjection.js +127 -0
- package/dist/esm/session/createSessionClient.js +9 -2
- package/dist/esm/shared/utils/debugUtils.js +3 -3
- package/dist/esm/utils/authWebUrl.js +9 -29
- package/dist/esm/utils/coldBoot.js +10 -8
- package/dist/esm/utils/{fapiAutoDetect.js → registrableApex.js} +8 -10
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/mixins/OxyServices.accounts.d.ts +24 -27
- package/dist/types/mixins/index.d.ts +1 -2
- package/dist/types/models/session.d.ts +4 -5
- package/dist/types/server/index.d.ts +1 -1
- package/dist/types/session/SessionClient.d.ts +52 -1
- package/dist/types/session/accountDialogController.d.ts +246 -0
- package/dist/types/session/accountProjection.d.ts +142 -0
- package/dist/types/session/createSessionClient.d.ts +9 -2
- package/dist/types/shared/utils/debugUtils.d.ts +3 -3
- package/dist/types/utils/accountUtils.d.ts +2 -3
- package/dist/types/utils/authWebUrl.d.ts +9 -29
- package/dist/types/utils/coldBoot.d.ts +17 -14
- package/dist/types/utils/{fapiAutoDetect.d.ts → registrableApex.d.ts} +8 -10
- package/package.json +2 -2
- package/src/HttpService.ts +1 -1
- package/src/index.ts +43 -11
- package/src/mixins/OxyServices.accounts.ts +21 -26
- package/src/mixins/index.ts +0 -7
- package/src/models/session.ts +4 -5
- package/src/server/index.ts +1 -1
- package/src/session/SessionClient.ts +202 -12
- package/src/session/__tests__/SessionClient.signedOut.test.ts +224 -0
- package/src/session/__tests__/accountDialogController.test.ts +469 -0
- package/src/session/__tests__/accountProjection.test.ts +181 -0
- package/src/session/accountDialogController.ts +682 -0
- package/src/session/accountProjection.ts +263 -0
- package/src/session/createSessionClient.ts +9 -2
- package/src/shared/utils/debugUtils.ts +3 -3
- package/src/utils/__tests__/authWebUrl.test.ts +5 -16
- package/src/utils/__tests__/{fapiAutoDetect.test.ts → registrableApex.test.ts} +1 -1
- package/src/utils/accountUtils.ts +2 -3
- package/src/utils/authWebUrl.ts +9 -30
- package/src/utils/coldBoot.ts +17 -14
- package/src/utils/{fapiAutoDetect.ts → registrableApex.ts} +8 -10
- package/dist/cjs/mixins/OxyServices.authorizedApps.js +0 -38
- package/dist/esm/mixins/OxyServices.authorizedApps.js +0 -35
- package/dist/types/mixins/OxyServices.authorizedApps.d.ts +0 -94
- package/src/mixins/OxyServices.authorizedApps.ts +0 -75
- package/src/mixins/__tests__/authorizedApps.test.ts +0 -63
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authorized-apps mixin — the "Connected apps" management surface that survived
|
|
3
|
-
* the FedCM removal.
|
|
4
|
-
*
|
|
5
|
-
* These two methods read/revoke the user's LEGACY FedCM authorization grants
|
|
6
|
-
* (`GET`/`DELETE /fedcm/me/authorized-apps`). They are the last live consumers
|
|
7
|
-
* of that endpoint (services' `ConnectedAppsScreen` via `useAccountQueries` /
|
|
8
|
-
* `useAccountMutations`) and stay until the AppGrant migration retires the
|
|
9
|
-
* FedCM grant store. All FedCM SIGN-IN machinery was deleted with
|
|
10
|
-
* `OxyServices.fedcm.ts`; this is management-only, so it has no dependency on
|
|
11
|
-
* the credential/nonce pipeline.
|
|
12
|
-
*/
|
|
13
|
-
import type { OxyServicesBase } from '../OxyServices.base';
|
|
14
|
-
/**
|
|
15
|
-
* Public summary of an RP application the user has authorized — mirrors the
|
|
16
|
-
* `AuthorizedAppSummary` shape returned by `GET /fedcm/me/authorized-apps`.
|
|
17
|
-
*/
|
|
18
|
-
export interface AuthorizedApp {
|
|
19
|
-
/** Normalised RP origin. */
|
|
20
|
-
origin: string;
|
|
21
|
-
/** Friendly display name. */
|
|
22
|
-
name: string;
|
|
23
|
-
/** Optional human-readable description. */
|
|
24
|
-
description?: string;
|
|
25
|
-
/** ISO-8601 timestamp of when the user first authorized this RP. */
|
|
26
|
-
firstGrantedAt: string;
|
|
27
|
-
/** ISO-8601 timestamp of the most recent FedCM exchange for this user+RP. */
|
|
28
|
-
lastUsedAt: string;
|
|
29
|
-
}
|
|
30
|
-
export declare function OxyServicesAuthorizedAppsMixin<T extends typeof OxyServicesBase>(Base: T): {
|
|
31
|
-
new (...args: any[]): {
|
|
32
|
-
/**
|
|
33
|
-
* List the authenticated user's authorized RP apps — the intersection of the
|
|
34
|
-
* user's FedCM grants and the currently-approved RP catalog. Powers the
|
|
35
|
-
* "Connected apps" management UI. Requires a real user session.
|
|
36
|
-
*/
|
|
37
|
-
listAuthorizedApps(): Promise<AuthorizedApp[]>;
|
|
38
|
-
/**
|
|
39
|
-
* Revoke the authenticated user's authorization for a specific RP origin.
|
|
40
|
-
* The corresponding cache entry is invalidated so a subsequent
|
|
41
|
-
* `listAuthorizedApps()` sees fresh data.
|
|
42
|
-
*/
|
|
43
|
-
revokeAuthorizedApp(origin: string): Promise<void>;
|
|
44
|
-
httpService: import("../HttpService").HttpService;
|
|
45
|
-
cloudURL: string;
|
|
46
|
-
config: import("../OxyServices.base").OxyConfig;
|
|
47
|
-
__resetTokensForTests(): void;
|
|
48
|
-
makeRequest<T_1>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", url: string, data?: any, options?: import("../HttpService").RequestOptions): Promise<T_1>;
|
|
49
|
-
getBaseURL(): string;
|
|
50
|
-
getClient(): import("../HttpService").HttpService;
|
|
51
|
-
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
52
|
-
getMetrics(): {
|
|
53
|
-
totalRequests: number;
|
|
54
|
-
successfulRequests: number;
|
|
55
|
-
failedRequests: number;
|
|
56
|
-
cacheHits: number;
|
|
57
|
-
cacheMisses: number;
|
|
58
|
-
averageResponseTime: number;
|
|
59
|
-
};
|
|
60
|
-
clearCache(): void;
|
|
61
|
-
clearCacheEntry(key: string): void;
|
|
62
|
-
clearCacheByPrefix(prefix: string): number;
|
|
63
|
-
getCacheStats(): {
|
|
64
|
-
size: number;
|
|
65
|
-
hits: number;
|
|
66
|
-
misses: number;
|
|
67
|
-
hitRate: number;
|
|
68
|
-
};
|
|
69
|
-
getCloudURL(): string;
|
|
70
|
-
setTokens(accessToken: string): void;
|
|
71
|
-
clearTokens(): void;
|
|
72
|
-
onTokensChanged(listener: (accessToken: string | null) => void): () => void;
|
|
73
|
-
_cachedUserId: string | null | undefined;
|
|
74
|
-
_cachedAccessToken: string | null;
|
|
75
|
-
getCurrentUserId(): string | null;
|
|
76
|
-
hasValidToken(): boolean;
|
|
77
|
-
getAccessToken(): string | null;
|
|
78
|
-
getAccessTokenExpiry(): number | null;
|
|
79
|
-
waitForAuth(timeoutMs?: number): Promise<boolean>;
|
|
80
|
-
withAuthRetry<T_1>(operation: () => Promise<T_1>, operationName: string, options?: {
|
|
81
|
-
maxRetries?: number;
|
|
82
|
-
retryDelay?: number;
|
|
83
|
-
authTimeoutMs?: number;
|
|
84
|
-
}): Promise<T_1>;
|
|
85
|
-
validate(): Promise<boolean>;
|
|
86
|
-
handleError(error: unknown): Error;
|
|
87
|
-
healthCheck(): Promise<{
|
|
88
|
-
status: string;
|
|
89
|
-
users?: number;
|
|
90
|
-
timestamp?: string;
|
|
91
|
-
[key: string]: any;
|
|
92
|
-
}>;
|
|
93
|
-
};
|
|
94
|
-
} & T;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authorized-apps mixin — the "Connected apps" management surface that survived
|
|
3
|
-
* the FedCM removal.
|
|
4
|
-
*
|
|
5
|
-
* These two methods read/revoke the user's LEGACY FedCM authorization grants
|
|
6
|
-
* (`GET`/`DELETE /fedcm/me/authorized-apps`). They are the last live consumers
|
|
7
|
-
* of that endpoint (services' `ConnectedAppsScreen` via `useAccountQueries` /
|
|
8
|
-
* `useAccountMutations`) and stay until the AppGrant migration retires the
|
|
9
|
-
* FedCM grant store. All FedCM SIGN-IN machinery was deleted with
|
|
10
|
-
* `OxyServices.fedcm.ts`; this is management-only, so it has no dependency on
|
|
11
|
-
* the credential/nonce pipeline.
|
|
12
|
-
*/
|
|
13
|
-
import type { OxyServicesBase } from '../OxyServices.base';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Public summary of an RP application the user has authorized — mirrors the
|
|
17
|
-
* `AuthorizedAppSummary` shape returned by `GET /fedcm/me/authorized-apps`.
|
|
18
|
-
*/
|
|
19
|
-
export interface AuthorizedApp {
|
|
20
|
-
/** Normalised RP origin. */
|
|
21
|
-
origin: string;
|
|
22
|
-
/** Friendly display name. */
|
|
23
|
-
name: string;
|
|
24
|
-
/** Optional human-readable description. */
|
|
25
|
-
description?: string;
|
|
26
|
-
/** ISO-8601 timestamp of when the user first authorized this RP. */
|
|
27
|
-
firstGrantedAt: string;
|
|
28
|
-
/** ISO-8601 timestamp of the most recent FedCM exchange for this user+RP. */
|
|
29
|
-
lastUsedAt: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function OxyServicesAuthorizedAppsMixin<T extends typeof OxyServicesBase>(Base: T) {
|
|
33
|
-
return class extends Base {
|
|
34
|
-
/**
|
|
35
|
-
* List the authenticated user's authorized RP apps — the intersection of the
|
|
36
|
-
* user's FedCM grants and the currently-approved RP catalog. Powers the
|
|
37
|
-
* "Connected apps" management UI. Requires a real user session.
|
|
38
|
-
*/
|
|
39
|
-
async listAuthorizedApps(): Promise<AuthorizedApp[]> {
|
|
40
|
-
try {
|
|
41
|
-
const response = await this.makeRequest<{ apps: AuthorizedApp[] }>(
|
|
42
|
-
'GET',
|
|
43
|
-
'/fedcm/me/authorized-apps',
|
|
44
|
-
undefined,
|
|
45
|
-
{
|
|
46
|
-
cache: true,
|
|
47
|
-
cacheTTL: 30 * 1000, // 30 second cache — short, this drives a manageable UI
|
|
48
|
-
},
|
|
49
|
-
);
|
|
50
|
-
return response?.apps ?? [];
|
|
51
|
-
} catch (error) {
|
|
52
|
-
throw this.handleError(error);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Revoke the authenticated user's authorization for a specific RP origin.
|
|
58
|
-
* The corresponding cache entry is invalidated so a subsequent
|
|
59
|
-
* `listAuthorizedApps()` sees fresh data.
|
|
60
|
-
*/
|
|
61
|
-
async revokeAuthorizedApp(origin: string): Promise<void> {
|
|
62
|
-
try {
|
|
63
|
-
await this.makeRequest(
|
|
64
|
-
'DELETE',
|
|
65
|
-
`/fedcm/me/authorized-apps/${encodeURIComponent(origin)}`,
|
|
66
|
-
undefined,
|
|
67
|
-
{ cache: false },
|
|
68
|
-
);
|
|
69
|
-
this.clearCacheEntry('GET:/fedcm/me/authorized-apps');
|
|
70
|
-
} catch (error) {
|
|
71
|
-
throw this.handleError(error);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authorized-apps mixin tests — the "Connected apps" management pair that
|
|
3
|
-
* survived the FedCM removal. Stubs `makeRequest` (no network).
|
|
4
|
-
*/
|
|
5
|
-
import type { AuthorizedApp } from '../OxyServices.authorizedApps';
|
|
6
|
-
import { OxyServices } from '../../OxyServices';
|
|
7
|
-
|
|
8
|
-
const APP: AuthorizedApp = {
|
|
9
|
-
origin: 'https://mention.earth',
|
|
10
|
-
name: 'Mention',
|
|
11
|
-
firstGrantedAt: '2026-01-01T00:00:00.000Z',
|
|
12
|
-
lastUsedAt: '2026-06-01T00:00:00.000Z',
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
describe('OxyServices.authorizedApps', () => {
|
|
16
|
-
let oxy: OxyServices;
|
|
17
|
-
let makeRequest: jest.SpyInstance;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
oxy = new OxyServices({ baseURL: 'http://test.invalid' });
|
|
21
|
-
makeRequest = jest.spyOn(oxy, 'makeRequest');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
afterEach(() => jest.restoreAllMocks());
|
|
25
|
-
|
|
26
|
-
describe('listAuthorizedApps', () => {
|
|
27
|
-
it('GETs the authorized-apps and returns the array', async () => {
|
|
28
|
-
makeRequest.mockResolvedValueOnce({ apps: [APP] });
|
|
29
|
-
expect(await oxy.listAuthorizedApps()).toEqual([APP]);
|
|
30
|
-
expect(makeRequest).toHaveBeenCalledWith(
|
|
31
|
-
'GET',
|
|
32
|
-
'/fedcm/me/authorized-apps',
|
|
33
|
-
undefined,
|
|
34
|
-
expect.objectContaining({ cache: true }),
|
|
35
|
-
);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('defaults to [] when the response has no apps', async () => {
|
|
39
|
-
makeRequest.mockResolvedValueOnce({});
|
|
40
|
-
expect(await oxy.listAuthorizedApps()).toEqual([]);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('defaults to [] when the response is null (no throw on null access)', async () => {
|
|
44
|
-
makeRequest.mockResolvedValueOnce(null);
|
|
45
|
-
expect(await oxy.listAuthorizedApps()).toEqual([]);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('revokeAuthorizedApp', () => {
|
|
50
|
-
it('DELETEs the encoded origin and sweeps the list cache', async () => {
|
|
51
|
-
const clearCacheEntry = jest.spyOn(oxy, 'clearCacheEntry');
|
|
52
|
-
makeRequest.mockResolvedValueOnce(undefined);
|
|
53
|
-
await oxy.revokeAuthorizedApp('https://mention.earth');
|
|
54
|
-
expect(makeRequest).toHaveBeenCalledWith(
|
|
55
|
-
'DELETE',
|
|
56
|
-
'/fedcm/me/authorized-apps/https%3A%2F%2Fmention.earth',
|
|
57
|
-
undefined,
|
|
58
|
-
{ cache: false },
|
|
59
|
-
);
|
|
60
|
-
expect(clearCacheEntry).toHaveBeenCalledWith('GET:/fedcm/me/authorized-apps');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
});
|