@aspect-wallet/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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +708 -0
- package/dist/audit/history.d.ts +44 -0
- package/dist/audit/history.d.ts.map +1 -0
- package/dist/audit/history.js +80 -0
- package/dist/audit/history.js.map +1 -0
- package/dist/auth/email.d.ts +52 -0
- package/dist/auth/email.d.ts.map +1 -0
- package/dist/auth/email.js +66 -0
- package/dist/auth/email.js.map +1 -0
- package/dist/auth/oauth.d.ts +47 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +103 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/passkey-auth.d.ts +39 -0
- package/dist/auth/passkey-auth.d.ts.map +1 -0
- package/dist/auth/passkey-auth.js +108 -0
- package/dist/auth/passkey-auth.js.map +1 -0
- package/dist/auth/session.d.ts +30 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +61 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/chain/registry.d.ts +25 -0
- package/dist/chain/registry.d.ts.map +1 -0
- package/dist/chain/registry.js +46 -0
- package/dist/chain/registry.js.map +1 -0
- package/dist/core/client.d.ts +78 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +129 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/config.d.ts +22 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +91 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.d.ts +32 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +95 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/mfa/guardian.d.ts +27 -0
- package/dist/mfa/guardian.d.ts.map +1 -0
- package/dist/mfa/guardian.js +37 -0
- package/dist/mfa/guardian.js.map +1 -0
- package/dist/mfa/multisig.d.ts +28 -0
- package/dist/mfa/multisig.d.ts.map +1 -0
- package/dist/mfa/multisig.js +40 -0
- package/dist/mfa/multisig.js.map +1 -0
- package/dist/mfa/tiers.d.ts +34 -0
- package/dist/mfa/tiers.d.ts.map +1 -0
- package/dist/mfa/tiers.js +66 -0
- package/dist/mfa/tiers.js.map +1 -0
- package/dist/mfa/timelock.d.ts +32 -0
- package/dist/mfa/timelock.d.ts.map +1 -0
- package/dist/mfa/timelock.js +47 -0
- package/dist/mfa/timelock.js.map +1 -0
- package/dist/recovery/devices.d.ts +31 -0
- package/dist/recovery/devices.d.ts.map +1 -0
- package/dist/recovery/devices.js +33 -0
- package/dist/recovery/devices.js.map +1 -0
- package/dist/recovery/export.d.ts +33 -0
- package/dist/recovery/export.d.ts.map +1 -0
- package/dist/recovery/export.js +44 -0
- package/dist/recovery/export.js.map +1 -0
- package/dist/recovery/rotation.d.ts +26 -0
- package/dist/recovery/rotation.d.ts.map +1 -0
- package/dist/recovery/rotation.js +31 -0
- package/dist/recovery/rotation.js.map +1 -0
- package/dist/recovery/social.d.ts +33 -0
- package/dist/recovery/social.d.ts.map +1 -0
- package/dist/recovery/social.js +36 -0
- package/dist/recovery/social.js.map +1 -0
- package/dist/security/freeze.d.ts +34 -0
- package/dist/security/freeze.d.ts.map +1 -0
- package/dist/security/freeze.js +42 -0
- package/dist/security/freeze.js.map +1 -0
- package/dist/security/revoke.d.ts +27 -0
- package/dist/security/revoke.d.ts.map +1 -0
- package/dist/security/revoke.js +27 -0
- package/dist/security/revoke.js.map +1 -0
- package/dist/security/watchtower.d.ts +34 -0
- package/dist/security/watchtower.d.ts.map +1 -0
- package/dist/security/watchtower.js +38 -0
- package/dist/security/watchtower.js.map +1 -0
- package/dist/session-keys/manager.d.ts +40 -0
- package/dist/session-keys/manager.d.ts.map +1 -0
- package/dist/session-keys/manager.js +65 -0
- package/dist/session-keys/manager.js.map +1 -0
- package/dist/session-keys/permissions.d.ts +44 -0
- package/dist/session-keys/permissions.d.ts.map +1 -0
- package/dist/session-keys/permissions.js +63 -0
- package/dist/session-keys/permissions.js.map +1 -0
- package/dist/session-keys/templates.d.ts +49 -0
- package/dist/session-keys/templates.d.ts.map +1 -0
- package/dist/session-keys/templates.js +65 -0
- package/dist/session-keys/templates.js.map +1 -0
- package/dist/signer/eoa.d.ts +24 -0
- package/dist/signer/eoa.d.ts.map +1 -0
- package/dist/signer/eoa.js +32 -0
- package/dist/signer/eoa.js.map +1 -0
- package/dist/signer/interface.d.ts +60 -0
- package/dist/signer/interface.d.ts.map +1 -0
- package/dist/signer/interface.js +47 -0
- package/dist/signer/interface.js.map +1 -0
- package/dist/signer/multisig.d.ts +38 -0
- package/dist/signer/multisig.d.ts.map +1 -0
- package/dist/signer/multisig.js +56 -0
- package/dist/signer/multisig.js.map +1 -0
- package/dist/signer/passkey.d.ts +35 -0
- package/dist/signer/passkey.d.ts.map +1 -0
- package/dist/signer/passkey.js +112 -0
- package/dist/signer/passkey.js.map +1 -0
- package/dist/signer/session.d.ts +24 -0
- package/dist/signer/session.d.ts.map +1 -0
- package/dist/signer/session.js +32 -0
- package/dist/signer/session.js.map +1 -0
- package/dist/sponsor/paymaster.d.ts +27 -0
- package/dist/sponsor/paymaster.d.ts.map +1 -0
- package/dist/sponsor/paymaster.js +43 -0
- package/dist/sponsor/paymaster.js.map +1 -0
- package/dist/transport/api.d.ts +25 -0
- package/dist/transport/api.d.ts.map +1 -0
- package/dist/transport/api.js +79 -0
- package/dist/transport/api.js.map +1 -0
- package/dist/transport/bundler.d.ts +52 -0
- package/dist/transport/bundler.d.ts.map +1 -0
- package/dist/transport/bundler.js +109 -0
- package/dist/transport/bundler.js.map +1 -0
- package/dist/transport/iframe.d.ts +33 -0
- package/dist/transport/iframe.d.ts.map +1 -0
- package/dist/transport/iframe.js +131 -0
- package/dist/transport/iframe.js.map +1 -0
- package/dist/types.d.ts +366 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/userop/builder.d.ts +75 -0
- package/dist/userop/builder.d.ts.map +1 -0
- package/dist/userop/builder.js +150 -0
- package/dist/userop/builder.js.map +1 -0
- package/dist/userop/encoding.d.ts +44 -0
- package/dist/userop/encoding.d.ts.map +1 -0
- package/dist/userop/encoding.js +99 -0
- package/dist/userop/encoding.js.map +1 -0
- package/dist/userop/gas.d.ts +35 -0
- package/dist/userop/gas.d.ts.map +1 -0
- package/dist/userop/gas.js +53 -0
- package/dist/userop/gas.js.map +1 -0
- package/dist/userop/hash.d.ts +34 -0
- package/dist/userop/hash.d.ts.map +1 -0
- package/dist/userop/hash.js +55 -0
- package/dist/userop/hash.js.map +1 -0
- package/dist/userop/nonce.d.ts +53 -0
- package/dist/userop/nonce.d.ts.map +1 -0
- package/dist/userop/nonce.js +79 -0
- package/dist/userop/nonce.js.map +1 -0
- package/dist/wallet/factory.d.ts +63 -0
- package/dist/wallet/factory.d.ts.map +1 -0
- package/dist/wallet/factory.js +63 -0
- package/dist/wallet/factory.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit history and event streaming.
|
|
3
|
+
* Corresponds to SPEC-013 Section 12.
|
|
4
|
+
*/
|
|
5
|
+
import type { Address, AuditHistoryQuery, AuditHistoryResult, WebhookConfig, WebhookInfo } from '../types.js';
|
|
6
|
+
import { ApiClient } from '../transport/api.js';
|
|
7
|
+
/**
|
|
8
|
+
* Audit module for querying operation history, event streams, and webhook management.
|
|
9
|
+
*/
|
|
10
|
+
export declare class AuditClient {
|
|
11
|
+
private readonly api;
|
|
12
|
+
readonly webhooks: WebhookManager;
|
|
13
|
+
constructor(api: ApiClient);
|
|
14
|
+
/** Get full operation history for a wallet */
|
|
15
|
+
getHistory(address: Address, query?: AuditHistoryQuery): Promise<AuditHistoryResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to real-time events for a wallet.
|
|
18
|
+
* Returns an unsubscribe function.
|
|
19
|
+
*/
|
|
20
|
+
subscribe(address: Address, options: {
|
|
21
|
+
events: string[];
|
|
22
|
+
onEvent: (event: {
|
|
23
|
+
type: string;
|
|
24
|
+
userOpHash?: string;
|
|
25
|
+
success?: boolean;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}) => void;
|
|
28
|
+
onError?: (error: Error) => void;
|
|
29
|
+
}): () => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Webhook management for server-side notifications.
|
|
33
|
+
*/
|
|
34
|
+
export declare class WebhookManager {
|
|
35
|
+
private readonly api;
|
|
36
|
+
constructor(api: ApiClient);
|
|
37
|
+
/** Register a new webhook */
|
|
38
|
+
create(config: WebhookConfig): Promise<WebhookInfo>;
|
|
39
|
+
/** List all registered webhooks */
|
|
40
|
+
list(): Promise<WebhookInfo[]>;
|
|
41
|
+
/** Remove a webhook */
|
|
42
|
+
remove(webhookId: string): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/audit/history.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;GAEG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;gBAEL,GAAG,EAAE,SAAS;IAI3C,8CAA8C;IACxC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAc1F;;;OAGG;IACH,SAAS,CACP,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAC;YAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,KAAK,IAAI,CAAC;QAC3G,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KAClC,GACA,MAAM,IAAI;CAwBd;AAED;;GAEG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,SAAS;IAE3C,6BAA6B;IACvB,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IAIzD,mCAAmC;IAC7B,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIpC,uBAAuB;IACjB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit history and event streaming.
|
|
3
|
+
* Corresponds to SPEC-013 Section 12.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Audit module for querying operation history, event streams, and webhook management.
|
|
7
|
+
*/
|
|
8
|
+
export class AuditClient {
|
|
9
|
+
api;
|
|
10
|
+
webhooks;
|
|
11
|
+
constructor(api) {
|
|
12
|
+
this.api = api;
|
|
13
|
+
this.webhooks = new WebhookManager(api);
|
|
14
|
+
}
|
|
15
|
+
/** Get full operation history for a wallet */
|
|
16
|
+
async getHistory(address, query) {
|
|
17
|
+
const params = {};
|
|
18
|
+
if (query?.limit != null)
|
|
19
|
+
params['limit'] = query.limit.toString();
|
|
20
|
+
if (query?.offset != null)
|
|
21
|
+
params['offset'] = query.offset.toString();
|
|
22
|
+
if (query?.from)
|
|
23
|
+
params['from'] = query.from;
|
|
24
|
+
if (query?.to)
|
|
25
|
+
params['to'] = query.to;
|
|
26
|
+
if (query?.types)
|
|
27
|
+
params['types'] = query.types.join(',');
|
|
28
|
+
return this.api.get(`/audit/history`, {
|
|
29
|
+
wallet: address,
|
|
30
|
+
...params,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Subscribe to real-time events for a wallet.
|
|
35
|
+
* Returns an unsubscribe function.
|
|
36
|
+
*/
|
|
37
|
+
subscribe(address, options) {
|
|
38
|
+
const params = new URLSearchParams({
|
|
39
|
+
wallet: address,
|
|
40
|
+
events: options.events.join(','),
|
|
41
|
+
});
|
|
42
|
+
const baseUrl = this.api.baseUrl;
|
|
43
|
+
const eventSource = new EventSource(`${baseUrl}/audit/events?${params.toString()}`);
|
|
44
|
+
eventSource.onmessage = (event) => {
|
|
45
|
+
try {
|
|
46
|
+
const data = JSON.parse(event.data);
|
|
47
|
+
options.onEvent(data);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
eventSource.onerror = () => {
|
|
54
|
+
options.onError?.(new Error('Event stream connection error'));
|
|
55
|
+
};
|
|
56
|
+
return () => eventSource.close();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Webhook management for server-side notifications.
|
|
61
|
+
*/
|
|
62
|
+
export class WebhookManager {
|
|
63
|
+
api;
|
|
64
|
+
constructor(api) {
|
|
65
|
+
this.api = api;
|
|
66
|
+
}
|
|
67
|
+
/** Register a new webhook */
|
|
68
|
+
async create(config) {
|
|
69
|
+
return this.api.post('/audit/webhooks', config);
|
|
70
|
+
}
|
|
71
|
+
/** List all registered webhooks */
|
|
72
|
+
async list() {
|
|
73
|
+
return this.api.get('/audit/webhooks');
|
|
74
|
+
}
|
|
75
|
+
/** Remove a webhook */
|
|
76
|
+
async remove(webhookId) {
|
|
77
|
+
await this.api.delete(`/audit/webhooks/${webhookId}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/audit/history.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email OTP authentication flow.
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.1.
|
|
4
|
+
*
|
|
5
|
+
* Flow:
|
|
6
|
+
* 1. Send OTP to user's email
|
|
7
|
+
* 2. User enters OTP code
|
|
8
|
+
* 3. Verify OTP -> returns session + wallet info
|
|
9
|
+
* 4. First-time: Turnkey sub-org created, key generated, wallet address computed
|
|
10
|
+
* 5. Returning: existing key loaded
|
|
11
|
+
*/
|
|
12
|
+
import { ApiClient } from '../transport/api.js';
|
|
13
|
+
import { SessionManager } from './session.js';
|
|
14
|
+
import type { SessionInfo } from '../types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Email OTP authentication client.
|
|
17
|
+
* Handles the two-step email verification flow.
|
|
18
|
+
*/
|
|
19
|
+
export declare class AuthClient {
|
|
20
|
+
private readonly api;
|
|
21
|
+
readonly session: SessionManager;
|
|
22
|
+
constructor(api: ApiClient);
|
|
23
|
+
/**
|
|
24
|
+
* Send an OTP code to the user's email address.
|
|
25
|
+
* Rate limited: 5/hour per email.
|
|
26
|
+
*/
|
|
27
|
+
sendEmailOtp(email: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Verify the OTP code and establish a session.
|
|
30
|
+
* Rate limited: 3 attempts per OTP.
|
|
31
|
+
*
|
|
32
|
+
* @returns Session info including JWT, user, wallet, and signer details
|
|
33
|
+
*/
|
|
34
|
+
verifyEmailOtp(params: {
|
|
35
|
+
email: string;
|
|
36
|
+
code: string;
|
|
37
|
+
}): Promise<SessionInfo>;
|
|
38
|
+
/** Check if the user is authenticated */
|
|
39
|
+
isAuthenticated(): boolean;
|
|
40
|
+
/** Get the current session */
|
|
41
|
+
getSession(): SessionInfo | null;
|
|
42
|
+
/** Refresh the current session */
|
|
43
|
+
refreshSession(): Promise<SessionInfo>;
|
|
44
|
+
/** Logout and revoke session */
|
|
45
|
+
logout(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Link an email to an existing account (for backup auth).
|
|
48
|
+
* Sends an OTP to the new email for verification.
|
|
49
|
+
*/
|
|
50
|
+
linkEmail(email: string): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=email.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/auth/email.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;GAGG;AACH,qBAAa,UAAU;IAGT,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;gBAEJ,GAAG,EAAE,SAAS;IAI3C;;;OAGG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD;;;;;OAKG;IACG,cAAc,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAMnF,yCAAyC;IACzC,eAAe,IAAI,OAAO;IAI1B,8BAA8B;IAC9B,UAAU,IAAI,WAAW,GAAG,IAAI;IAIhC,kCAAkC;IAC5B,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAI5C,gCAAgC;IAC1B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B;;;OAGG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9C"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email OTP authentication flow.
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.1.
|
|
4
|
+
*
|
|
5
|
+
* Flow:
|
|
6
|
+
* 1. Send OTP to user's email
|
|
7
|
+
* 2. User enters OTP code
|
|
8
|
+
* 3. Verify OTP -> returns session + wallet info
|
|
9
|
+
* 4. First-time: Turnkey sub-org created, key generated, wallet address computed
|
|
10
|
+
* 5. Returning: existing key loaded
|
|
11
|
+
*/
|
|
12
|
+
import { SessionManager } from './session.js';
|
|
13
|
+
/**
|
|
14
|
+
* Email OTP authentication client.
|
|
15
|
+
* Handles the two-step email verification flow.
|
|
16
|
+
*/
|
|
17
|
+
export class AuthClient {
|
|
18
|
+
api;
|
|
19
|
+
session;
|
|
20
|
+
constructor(api) {
|
|
21
|
+
this.api = api;
|
|
22
|
+
this.session = new SessionManager(api);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Send an OTP code to the user's email address.
|
|
26
|
+
* Rate limited: 5/hour per email.
|
|
27
|
+
*/
|
|
28
|
+
async sendEmailOtp(email) {
|
|
29
|
+
await this.api.post('/auth/email/otp', { email });
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Verify the OTP code and establish a session.
|
|
33
|
+
* Rate limited: 3 attempts per OTP.
|
|
34
|
+
*
|
|
35
|
+
* @returns Session info including JWT, user, wallet, and signer details
|
|
36
|
+
*/
|
|
37
|
+
async verifyEmailOtp(params) {
|
|
38
|
+
const session = await this.api.post('/auth/email/verify', params);
|
|
39
|
+
this.session.setSession(session);
|
|
40
|
+
return session;
|
|
41
|
+
}
|
|
42
|
+
/** Check if the user is authenticated */
|
|
43
|
+
isAuthenticated() {
|
|
44
|
+
return this.session.isAuthenticated();
|
|
45
|
+
}
|
|
46
|
+
/** Get the current session */
|
|
47
|
+
getSession() {
|
|
48
|
+
return this.session.getSession();
|
|
49
|
+
}
|
|
50
|
+
/** Refresh the current session */
|
|
51
|
+
async refreshSession() {
|
|
52
|
+
return this.session.refreshSession();
|
|
53
|
+
}
|
|
54
|
+
/** Logout and revoke session */
|
|
55
|
+
async logout() {
|
|
56
|
+
return this.session.logout();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Link an email to an existing account (for backup auth).
|
|
60
|
+
* Sends an OTP to the new email for verification.
|
|
61
|
+
*/
|
|
62
|
+
async linkEmail(email) {
|
|
63
|
+
await this.api.post('/auth/link/email', { email });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/auth/email.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C;;;GAGG;AACH,MAAM,OAAO,UAAU;IAGQ;IAFpB,OAAO,CAAiB;IAEjC,YAA6B,GAAc;QAAd,QAAG,GAAH,GAAG,CAAW;QACzC,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa;QAC9B,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,MAAuC;QAC1D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAc,oBAAoB,EAAE,MAAM,CAAC,CAAC;QAC/E,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,yCAAyC;IACzC,eAAe;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;IACxC,CAAC;IAED,8BAA8B;IAC9B,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IACnC,CAAC;IAED,kCAAkC;IAClC,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;IACvC,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS,CAAC,KAAa;QAC3B,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;CACF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth authentication flows (Google, Apple, Facebook).
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.2.
|
|
4
|
+
*
|
|
5
|
+
* All OAuth providers follow the same pattern:
|
|
6
|
+
* 1. Open OAuth popup/redirect
|
|
7
|
+
* 2. Exchange provider token with backend
|
|
8
|
+
* 3. Backend maps identity to Turnkey sub-org + signing key
|
|
9
|
+
* 4. Returns session info with wallet address
|
|
10
|
+
*/
|
|
11
|
+
import { ApiClient } from '../transport/api.js';
|
|
12
|
+
import { SessionManager } from './session.js';
|
|
13
|
+
import type { SessionInfo } from '../types.js';
|
|
14
|
+
type OAuthProvider = 'google' | 'apple' | 'facebook';
|
|
15
|
+
/**
|
|
16
|
+
* OAuth authentication client.
|
|
17
|
+
* Supports Google, Apple, and Facebook login flows.
|
|
18
|
+
* All providers create a Turnkey sub-org on first login and map to the same wallet
|
|
19
|
+
* when linking multiple auth methods.
|
|
20
|
+
*/
|
|
21
|
+
export declare class OAuthClient {
|
|
22
|
+
private readonly api;
|
|
23
|
+
private readonly session;
|
|
24
|
+
constructor(api: ApiClient, session: SessionManager);
|
|
25
|
+
/**
|
|
26
|
+
* Login with Google OAuth.
|
|
27
|
+
* Opens popup, exchanges token, maps to Turnkey key, returns session.
|
|
28
|
+
*/
|
|
29
|
+
loginWithGoogle(): Promise<SessionInfo>;
|
|
30
|
+
/**
|
|
31
|
+
* Login with Apple OAuth.
|
|
32
|
+
*/
|
|
33
|
+
loginWithApple(): Promise<SessionInfo>;
|
|
34
|
+
/**
|
|
35
|
+
* Login with Facebook OAuth.
|
|
36
|
+
*/
|
|
37
|
+
loginWithFacebook(): Promise<SessionInfo>;
|
|
38
|
+
/**
|
|
39
|
+
* Link an OAuth provider to an existing account.
|
|
40
|
+
* Same Turnkey sub-org, same wallet -- just adds an auth path.
|
|
41
|
+
*/
|
|
42
|
+
linkOAuthProvider(provider: OAuthProvider): Promise<void>;
|
|
43
|
+
private loginWithProvider;
|
|
44
|
+
private openOAuthPopup;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAErD;;;;;GAKG;AACH,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,cAAc;IAG1C;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC;IAI7C;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAI5C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC;IAI/C;;;OAGG;IACG,iBAAiB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;YAIjD,iBAAiB;IAmB/B,OAAO,CAAC,cAAc;CAmDvB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth authentication flows (Google, Apple, Facebook).
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.2.
|
|
4
|
+
*
|
|
5
|
+
* All OAuth providers follow the same pattern:
|
|
6
|
+
* 1. Open OAuth popup/redirect
|
|
7
|
+
* 2. Exchange provider token with backend
|
|
8
|
+
* 3. Backend maps identity to Turnkey sub-org + signing key
|
|
9
|
+
* 4. Returns session info with wallet address
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* OAuth authentication client.
|
|
13
|
+
* Supports Google, Apple, and Facebook login flows.
|
|
14
|
+
* All providers create a Turnkey sub-org on first login and map to the same wallet
|
|
15
|
+
* when linking multiple auth methods.
|
|
16
|
+
*/
|
|
17
|
+
export class OAuthClient {
|
|
18
|
+
api;
|
|
19
|
+
session;
|
|
20
|
+
constructor(api, session) {
|
|
21
|
+
this.api = api;
|
|
22
|
+
this.session = session;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Login with Google OAuth.
|
|
26
|
+
* Opens popup, exchanges token, maps to Turnkey key, returns session.
|
|
27
|
+
*/
|
|
28
|
+
async loginWithGoogle() {
|
|
29
|
+
return this.loginWithProvider('google');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Login with Apple OAuth.
|
|
33
|
+
*/
|
|
34
|
+
async loginWithApple() {
|
|
35
|
+
return this.loginWithProvider('apple');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Login with Facebook OAuth.
|
|
39
|
+
*/
|
|
40
|
+
async loginWithFacebook() {
|
|
41
|
+
return this.loginWithProvider('facebook');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Link an OAuth provider to an existing account.
|
|
45
|
+
* Same Turnkey sub-org, same wallet -- just adds an auth path.
|
|
46
|
+
*/
|
|
47
|
+
async linkOAuthProvider(provider) {
|
|
48
|
+
await this.api.post(`/auth/link/${provider}`, {});
|
|
49
|
+
}
|
|
50
|
+
async loginWithProvider(provider) {
|
|
51
|
+
// Get the OAuth redirect URL from the backend
|
|
52
|
+
const { authUrl } = await this.api.post(`/auth/oauth/${provider}/init`, { redirectUri: typeof window !== 'undefined' ? window.location.origin + '/auth/callback' : '' });
|
|
53
|
+
// In a browser, open a popup for the OAuth flow
|
|
54
|
+
const token = await this.openOAuthPopup(authUrl);
|
|
55
|
+
// Exchange the OAuth token for a session
|
|
56
|
+
const session = await this.api.post(`/auth/oauth/${provider}`, {
|
|
57
|
+
token,
|
|
58
|
+
});
|
|
59
|
+
this.session.setSession(session);
|
|
60
|
+
return session;
|
|
61
|
+
}
|
|
62
|
+
openOAuthPopup(authUrl) {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
if (typeof window === 'undefined') {
|
|
65
|
+
reject(new Error('OAuth popup requires a browser environment'));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const width = 500;
|
|
69
|
+
const height = 600;
|
|
70
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
71
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
72
|
+
const popup = window.open(authUrl, 'fcx-oauth', `width=${width},height=${height},left=${left},top=${top}`);
|
|
73
|
+
if (!popup) {
|
|
74
|
+
reject(new Error('Failed to open OAuth popup. Check popup blocker settings.'));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const handleMessage = (event) => {
|
|
78
|
+
if (event.data?.type === 'FCX_OAUTH_CALLBACK' && event.data?.token) {
|
|
79
|
+
window.removeEventListener('message', handleMessage);
|
|
80
|
+
popup.close();
|
|
81
|
+
resolve(event.data.token);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
window.addEventListener('message', handleMessage);
|
|
85
|
+
// Timeout after 5 minutes
|
|
86
|
+
const timeout = setTimeout(() => {
|
|
87
|
+
window.removeEventListener('message', handleMessage);
|
|
88
|
+
popup.close();
|
|
89
|
+
reject(new Error('OAuth flow timed out'));
|
|
90
|
+
}, 300_000);
|
|
91
|
+
// Check if popup was closed manually
|
|
92
|
+
const checkClosed = setInterval(() => {
|
|
93
|
+
if (popup.closed) {
|
|
94
|
+
clearInterval(checkClosed);
|
|
95
|
+
clearTimeout(timeout);
|
|
96
|
+
window.removeEventListener('message', handleMessage);
|
|
97
|
+
reject(new Error('OAuth popup closed by user'));
|
|
98
|
+
}
|
|
99
|
+
}, 1000);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passkey as authentication credential.
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.3.
|
|
4
|
+
*
|
|
5
|
+
* Flow:
|
|
6
|
+
* - Register: After initial login, create P256 key in device secure enclave
|
|
7
|
+
* - Login: Prompt biometric, sign challenge, backend verifies, issues session
|
|
8
|
+
*/
|
|
9
|
+
import { ApiClient } from '../transport/api.js';
|
|
10
|
+
import { SessionManager } from './session.js';
|
|
11
|
+
import type { SessionInfo } from '../types.js';
|
|
12
|
+
interface PasskeyCredential {
|
|
13
|
+
credentialId: string;
|
|
14
|
+
publicKey: string;
|
|
15
|
+
displayName: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Passkey authentication client.
|
|
19
|
+
* Handles WebAuthn credential registration and authentication flows.
|
|
20
|
+
*/
|
|
21
|
+
export declare class PasskeyAuthClient {
|
|
22
|
+
private readonly api;
|
|
23
|
+
private readonly session;
|
|
24
|
+
constructor(api: ApiClient, session: SessionManager);
|
|
25
|
+
/**
|
|
26
|
+
* Register a new passkey credential (after initial login via email/OAuth).
|
|
27
|
+
* Prompts biometric on device, stores P256 public key in backend and optionally on-chain.
|
|
28
|
+
*/
|
|
29
|
+
registerPasskey(params: {
|
|
30
|
+
displayName: string;
|
|
31
|
+
}): Promise<PasskeyCredential>;
|
|
32
|
+
/**
|
|
33
|
+
* Login with a registered passkey.
|
|
34
|
+
* Prompts biometric, signs challenge, backend verifies and issues session JWT.
|
|
35
|
+
*/
|
|
36
|
+
loginWithPasskey(): Promise<SessionInfo>;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=passkey-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-auth.d.ts","sourceRoot":"","sources":["../../src/auth/passkey-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,UAAU,iBAAiB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,cAAc;IAG1C;;;OAGG;IACG,eAAe,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6BlF;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC;CA6B/C"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passkey as authentication credential.
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.3.
|
|
4
|
+
*
|
|
5
|
+
* Flow:
|
|
6
|
+
* - Register: After initial login, create P256 key in device secure enclave
|
|
7
|
+
* - Login: Prompt biometric, sign challenge, backend verifies, issues session
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Passkey authentication client.
|
|
11
|
+
* Handles WebAuthn credential registration and authentication flows.
|
|
12
|
+
*/
|
|
13
|
+
export class PasskeyAuthClient {
|
|
14
|
+
api;
|
|
15
|
+
session;
|
|
16
|
+
constructor(api, session) {
|
|
17
|
+
this.api = api;
|
|
18
|
+
this.session = session;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Register a new passkey credential (after initial login via email/OAuth).
|
|
22
|
+
* Prompts biometric on device, stores P256 public key in backend and optionally on-chain.
|
|
23
|
+
*/
|
|
24
|
+
async registerPasskey(params) {
|
|
25
|
+
// Get creation options from server
|
|
26
|
+
const options = await this.api.post('/auth/passkey/register/options', { displayName: params.displayName });
|
|
27
|
+
if (typeof navigator === 'undefined' || !navigator.credentials) {
|
|
28
|
+
throw new Error('WebAuthn not available in this environment');
|
|
29
|
+
}
|
|
30
|
+
// Create credential
|
|
31
|
+
const credential = (await navigator.credentials.create({
|
|
32
|
+
publicKey: deserializeCreationOptions(options),
|
|
33
|
+
}));
|
|
34
|
+
const response = credential.response;
|
|
35
|
+
// Send credential to server for verification and storage
|
|
36
|
+
const result = await this.api.post('/auth/passkey/register', {
|
|
37
|
+
credentialId: bufferToBase64Url(credential.rawId),
|
|
38
|
+
attestationObject: bufferToBase64Url(response.attestationObject),
|
|
39
|
+
clientDataJSON: bufferToBase64Url(response.clientDataJSON),
|
|
40
|
+
displayName: params.displayName,
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Login with a registered passkey.
|
|
46
|
+
* Prompts biometric, signs challenge, backend verifies and issues session JWT.
|
|
47
|
+
*/
|
|
48
|
+
async loginWithPasskey() {
|
|
49
|
+
// Get authentication options from server
|
|
50
|
+
const options = await this.api.post('/auth/passkey/authenticate/options', {});
|
|
51
|
+
if (typeof navigator === 'undefined' || !navigator.credentials) {
|
|
52
|
+
throw new Error('WebAuthn not available in this environment');
|
|
53
|
+
}
|
|
54
|
+
// Get assertion
|
|
55
|
+
const assertion = (await navigator.credentials.get({
|
|
56
|
+
publicKey: deserializeRequestOptions(options),
|
|
57
|
+
}));
|
|
58
|
+
const response = assertion.response;
|
|
59
|
+
// Send to server for verification
|
|
60
|
+
const session = await this.api.post('/auth/passkey/authenticate', {
|
|
61
|
+
credentialId: bufferToBase64Url(assertion.rawId),
|
|
62
|
+
authenticatorData: bufferToBase64Url(response.authenticatorData),
|
|
63
|
+
clientDataJSON: bufferToBase64Url(response.clientDataJSON),
|
|
64
|
+
signature: bufferToBase64Url(response.signature),
|
|
65
|
+
});
|
|
66
|
+
this.session.setSession(session);
|
|
67
|
+
return session;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function bufferToBase64Url(buffer) {
|
|
71
|
+
const bytes = new Uint8Array(buffer);
|
|
72
|
+
let binary = '';
|
|
73
|
+
for (const byte of bytes) {
|
|
74
|
+
binary += String.fromCharCode(byte);
|
|
75
|
+
}
|
|
76
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
77
|
+
}
|
|
78
|
+
function deserializeCreationOptions(options) {
|
|
79
|
+
return {
|
|
80
|
+
...options,
|
|
81
|
+
challenge: base64UrlToBuffer(options.challenge),
|
|
82
|
+
user: {
|
|
83
|
+
...options.user,
|
|
84
|
+
id: base64UrlToBuffer(options.user.id),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function deserializeRequestOptions(options) {
|
|
89
|
+
return {
|
|
90
|
+
...options,
|
|
91
|
+
challenge: base64UrlToBuffer(options.challenge),
|
|
92
|
+
allowCredentials: options.allowCredentials?.map((cred) => ({
|
|
93
|
+
...cred,
|
|
94
|
+
id: base64UrlToBuffer(cred.id),
|
|
95
|
+
})),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function base64UrlToBuffer(base64url) {
|
|
99
|
+
const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
|
|
100
|
+
const padding = '='.repeat((4 - (base64.length % 4)) % 4);
|
|
101
|
+
const binary = atob(base64 + padding);
|
|
102
|
+
const bytes = new Uint8Array(binary.length);
|
|
103
|
+
for (let i = 0; i < binary.length; i++) {
|
|
104
|
+
bytes[i] = binary.charCodeAt(i);
|
|
105
|
+
}
|
|
106
|
+
return bytes.buffer;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=passkey-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-auth.js","sourceRoot":"","sources":["../../src/auth/passkey-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT session management.
|
|
3
|
+
* Corresponds to SPEC-013 Section 7.4.
|
|
4
|
+
*/
|
|
5
|
+
import { ApiClient } from '../transport/api.js';
|
|
6
|
+
import type { SessionInfo } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Manages authentication sessions (JWT lifecycle).
|
|
9
|
+
* Sessions are short-lived (1-24h), RS256 signed, and revocable.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SessionManager {
|
|
12
|
+
private readonly api;
|
|
13
|
+
private currentSession;
|
|
14
|
+
constructor(api: ApiClient);
|
|
15
|
+
/** Get the current session */
|
|
16
|
+
getSession(): SessionInfo | null;
|
|
17
|
+
/** Check if the user is authenticated with a valid session */
|
|
18
|
+
isAuthenticated(): boolean;
|
|
19
|
+
/** Set the session (called internally by auth flows) */
|
|
20
|
+
setSession(session: SessionInfo): void;
|
|
21
|
+
/** Refresh the current session */
|
|
22
|
+
refreshSession(): Promise<SessionInfo>;
|
|
23
|
+
/** Get session info from the server */
|
|
24
|
+
getServerSession(): Promise<SessionInfo>;
|
|
25
|
+
/** Logout and revoke the current session */
|
|
26
|
+
logout(): Promise<void>;
|
|
27
|
+
/** Clear the local session without server-side revocation */
|
|
28
|
+
clearLocal(): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;GAGG;AACH,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,OAAO,CAAC,cAAc,CAA4B;gBAErB,GAAG,EAAE,SAAS;IAE3C,8BAA8B;IAC9B,UAAU,IAAI,WAAW,GAAG,IAAI;IAOhC,8DAA8D;IAC9D,eAAe,IAAI,OAAO;IAI1B,wDAAwD;IACxD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAKtC,kCAAkC;IAC5B,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAa5C,uCAAuC;IACjC,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC;IAI9C,4CAA4C;IACtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B,6DAA6D;IAC7D,UAAU,IAAI,IAAI;CAInB"}
|