@oxyhq/core 3.10.1 → 3.11.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/AuthManager.js +9 -2
- package/dist/cjs/HttpService.js +27 -9
- package/dist/cjs/OxyServices.base.js +3 -2
- package/dist/cjs/crypto/canonicalJson.js +107 -0
- package/dist/cjs/crypto/keyManager.js +67 -8
- package/dist/cjs/crypto/signatureService.js +103 -0
- package/dist/cjs/index.js +15 -4
- package/dist/cjs/mixins/OxyServices.assets.js +16 -1
- package/dist/cjs/mixins/OxyServices.auth.js +190 -1
- package/dist/cjs/mixins/OxyServices.identity.js +291 -0
- package/dist/cjs/mixins/OxyServices.sso.js +28 -1
- package/dist/cjs/mixins/OxyServices.user.js +1 -0
- package/dist/cjs/mixins/index.js +3 -0
- package/dist/cjs/server/cors.js +20 -21
- package/dist/cjs/server/rateLimit.js +32 -8
- package/dist/cjs/utils/ssoReturn.js +1 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/AuthManager.js +9 -2
- package/dist/esm/HttpService.js +27 -9
- package/dist/esm/OxyServices.base.js +3 -2
- package/dist/esm/crypto/canonicalJson.js +104 -0
- package/dist/esm/crypto/keyManager.js +67 -8
- package/dist/esm/crypto/signatureService.js +102 -0
- package/dist/esm/index.js +9 -1
- package/dist/esm/mixins/OxyServices.assets.js +16 -1
- package/dist/esm/mixins/OxyServices.auth.js +190 -1
- package/dist/esm/mixins/OxyServices.identity.js +287 -0
- package/dist/esm/mixins/OxyServices.sso.js +28 -1
- package/dist/esm/mixins/OxyServices.user.js +1 -0
- package/dist/esm/mixins/index.js +3 -0
- package/dist/esm/server/cors.js +20 -21
- package/dist/esm/server/rateLimit.js +32 -8
- package/dist/esm/utils/ssoReturn.js +1 -1
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +3 -0
- package/dist/types/OxyServices.d.ts +2 -2
- package/dist/types/crypto/canonicalJson.d.ts +44 -0
- package/dist/types/crypto/keyManager.d.ts +7 -0
- package/dist/types/crypto/signatureService.d.ts +61 -0
- package/dist/types/index.d.ts +6 -2
- package/dist/types/mixins/OxyServices.auth.d.ts +136 -0
- package/dist/types/mixins/OxyServices.identity.d.ts +249 -0
- package/dist/types/mixins/OxyServices.sso.d.ts +4 -1
- package/dist/types/mixins/index.d.ts +2 -1
- package/dist/types/models/interfaces.d.ts +3 -0
- package/dist/types/server/cors.d.ts +5 -5
- package/dist/types/utils/ssoReturn.d.ts +1 -1
- package/package.json +2 -2
- package/src/AuthManager.ts +8 -2
- package/src/HttpService.ts +36 -8
- package/src/OxyServices.base.ts +3 -2
- package/src/OxyServices.ts +1 -1
- package/src/__tests__/authManager.security.test.ts +31 -0
- package/src/__tests__/httpServiceCsrf.test.ts +75 -0
- package/src/crypto/__tests__/canonicalJson.test.ts +116 -0
- package/src/crypto/__tests__/keyManager.atomicity.test.ts +41 -2
- package/src/crypto/__tests__/signChallengeShared.test.ts +64 -0
- package/src/crypto/__tests__/signedRecord.test.ts +125 -0
- package/src/crypto/canonicalJson.ts +120 -0
- package/src/crypto/keyManager.ts +62 -12
- package/src/crypto/signatureService.ts +126 -0
- package/src/index.ts +27 -2
- package/src/mixins/OxyServices.assets.ts +16 -1
- package/src/mixins/OxyServices.auth.ts +309 -1
- package/src/mixins/OxyServices.identity.ts +445 -0
- package/src/mixins/OxyServices.sso.ts +30 -1
- package/src/mixins/OxyServices.user.ts +1 -0
- package/src/mixins/__tests__/OxyServices.identity.test.ts +364 -0
- package/src/mixins/__tests__/assetCredentials.test.ts +47 -0
- package/src/mixins/__tests__/commonsSignIn.test.ts +277 -0
- package/src/mixins/__tests__/serviceAuth.test.ts +19 -0
- package/src/mixins/__tests__/sso.test.ts +31 -0
- package/src/mixins/index.ts +4 -0
- package/src/models/interfaces.ts +3 -0
- package/src/server/__tests__/cors.test.ts +5 -1
- package/src/server/__tests__/rateLimit.test.ts +116 -0
- package/src/server/cors.ts +25 -20
- package/src/server/rateLimit.ts +39 -8
- package/src/utils/__tests__/consumeSsoReturn.test.ts +1 -1
- package/src/utils/__tests__/ssoReturn.test.ts +1 -1
- package/src/utils/ssoReturn.ts +2 -2
|
@@ -25,6 +25,7 @@ export interface RequestOptions {
|
|
|
25
25
|
timeout?: number;
|
|
26
26
|
signal?: AbortSignal;
|
|
27
27
|
headers?: Record<string, string>;
|
|
28
|
+
responseType?: 'blob';
|
|
28
29
|
}
|
|
29
30
|
interface RequestConfig extends RequestOptions {
|
|
30
31
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
@@ -183,6 +184,8 @@ export declare class HttpService {
|
|
|
183
184
|
* Build full URL with query params
|
|
184
185
|
*/
|
|
185
186
|
private buildURL;
|
|
187
|
+
private getCredentialsMode;
|
|
188
|
+
private shouldSendCredentials;
|
|
186
189
|
/**
|
|
187
190
|
* Fetch CSRF token from server (with deduplication)
|
|
188
191
|
* Required for state-changing requests (POST, PUT, PATCH, DELETE)
|
|
@@ -122,7 +122,7 @@ export interface OxyServices extends InstanceType<ReturnType<typeof composeOxySe
|
|
|
122
122
|
waitForIframeAuth(iframe: HTMLIFrameElement, timeout: number, expectedOrigin: string): Promise<SessionLoginResponse | null>;
|
|
123
123
|
signInWithRedirect(options?: RedirectAuthOptions): void;
|
|
124
124
|
signUpWithRedirect(options?: RedirectAuthOptions): void;
|
|
125
|
-
exchangeSsoCode(code: string): Promise<SessionLoginResponse>;
|
|
125
|
+
exchangeSsoCode(code: string, state?: string): Promise<SessionLoginResponse>;
|
|
126
126
|
generateSsoState(): string;
|
|
127
127
|
auth(options?: {
|
|
128
128
|
debug?: boolean;
|
|
@@ -153,7 +153,7 @@ export declare const OXY_CLOUD_URL = "https://cloud.oxy.so";
|
|
|
153
153
|
/**
|
|
154
154
|
* Export the default Oxy API URL (for documentation)
|
|
155
155
|
*/
|
|
156
|
-
export declare const OXY_API_URL:
|
|
156
|
+
export declare const OXY_API_URL: string;
|
|
157
157
|
/**
|
|
158
158
|
* Pre-configured client instance for easy import
|
|
159
159
|
* Uses OXY_API_URL as baseURL and OXY_CLOUD_URL as cloudURL
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical JSON (RFC 8785 / JCS-style) serialization.
|
|
3
|
+
*
|
|
4
|
+
* `canonicalize(value)` produces a deterministic string for any JSON-compatible
|
|
5
|
+
* value so that a client which SIGNS a record and a server which VERIFIES it
|
|
6
|
+
* agree byte-for-byte on the signing input — regardless of the order in which
|
|
7
|
+
* object keys happen to be written, how the value was deserialized, or which
|
|
8
|
+
* runtime built it.
|
|
9
|
+
*
|
|
10
|
+
* This is the load-bearing primitive for the self-sovereign identity layer's
|
|
11
|
+
* signed records (`SignatureService.signRecord` + the API's record-verify path):
|
|
12
|
+
* both sides import THIS function from `@oxyhq/core`, so cross-implementation
|
|
13
|
+
* number/string formatting differences cannot cause a verify mismatch.
|
|
14
|
+
*
|
|
15
|
+
* Rules (the JSON Canonicalization Scheme subset we need):
|
|
16
|
+
* - Objects: keys are sorted (ascending, by UTF-16 code unit — the default
|
|
17
|
+
* `Array.prototype.sort` order) and serialized recursively. Properties whose
|
|
18
|
+
* value is `undefined`, a function, or a symbol are OMITTED (matching
|
|
19
|
+
* `JSON.stringify` object semantics).
|
|
20
|
+
* - Arrays: element order is PRESERVED; `undefined`/function/symbol elements
|
|
21
|
+
* serialize to `null` (matching `JSON.stringify` array semantics).
|
|
22
|
+
* - `null`, booleans, strings, and finite numbers serialize via the standard
|
|
23
|
+
* JSON representation.
|
|
24
|
+
* - Values exposing a `toJSON()` method (e.g. `Date`) are replaced by its
|
|
25
|
+
* result first, then serialized — so a `Date` and its ISO-string equivalent
|
|
26
|
+
* canonicalize identically (the wire always carries the string form).
|
|
27
|
+
* - Non-finite numbers (`NaN`, `Infinity`) and `bigint` are not part of the
|
|
28
|
+
* JSON data model and throw, rather than silently producing `null`.
|
|
29
|
+
*
|
|
30
|
+
* Platform-agnostic — zero dependencies, no `require()`, no react/react-native/
|
|
31
|
+
* expo. Safe in the dual CJS + ESM build.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Produce the canonical JSON string for `value`.
|
|
35
|
+
*
|
|
36
|
+
* Deterministic: two structurally-equal values yield identical strings even if
|
|
37
|
+
* their object keys were written in different orders. Use this — never an
|
|
38
|
+
* ad-hoc `JSON.stringify` of a hand-sorted object — as the signing input for
|
|
39
|
+
* signed records, so client signing and server verification cannot drift.
|
|
40
|
+
*
|
|
41
|
+
* @throws if `value` (or any nested member used as the top-level/primitive)
|
|
42
|
+
* contains a non-finite number or a `bigint`, which have no JSON form.
|
|
43
|
+
*/
|
|
44
|
+
export declare function canonicalize(value: unknown): string;
|
|
@@ -186,6 +186,13 @@ export declare class KeyManager {
|
|
|
186
186
|
* @internal
|
|
187
187
|
*/
|
|
188
188
|
private static _persistIdentityAtomic;
|
|
189
|
+
/**
|
|
190
|
+
* Restore the backup slot to a previously-snapshotted state. Best-effort so
|
|
191
|
+
* the original persistence error remains the one surfaced to the caller.
|
|
192
|
+
*
|
|
193
|
+
* @internal
|
|
194
|
+
*/
|
|
195
|
+
private static _rollbackBackup;
|
|
189
196
|
/**
|
|
190
197
|
* Restore the primary slot to a previously-snapshotted (privA, pubA) pair,
|
|
191
198
|
* or delete it entirely if there was no prior identity. Best-effort: every
|
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
* Handles signing and verification of messages using ECDSA secp256k1.
|
|
5
5
|
* Used for authenticating requests and proving identity ownership.
|
|
6
6
|
*/
|
|
7
|
+
import type { SignedRecordEnvelope } from '@oxyhq/contracts';
|
|
8
|
+
/**
|
|
9
|
+
* The signing-input portion of a {@link SignedRecordEnvelope}: every field
|
|
10
|
+
* EXCEPT the `publicKey` and `signature`. Both the client (when signing) and
|
|
11
|
+
* the server (when verifying) canonicalize exactly these fields, so they agree
|
|
12
|
+
* on the bytes that the signature covers.
|
|
13
|
+
*/
|
|
14
|
+
export type SignedRecordSigningFields = Pick<SignedRecordEnvelope, 'version' | 'type' | 'subject' | 'issuer' | 'record' | 'issuedAt'>;
|
|
15
|
+
/**
|
|
16
|
+
* Compute the canonical signing input for a signed-record envelope.
|
|
17
|
+
*
|
|
18
|
+
* This is the single definition of "what the signature covers": the canonical
|
|
19
|
+
* JSON of `{version, type, subject, issuer, record, issuedAt}`. `@oxyhq/core`
|
|
20
|
+
* (client signing) and `@oxyhq/api` (server verification) both call this, so a
|
|
21
|
+
* record signed by a client and verified by the server cannot drift.
|
|
22
|
+
*/
|
|
23
|
+
export declare function signedRecordSigningInput(fields: SignedRecordSigningFields): string;
|
|
7
24
|
export interface SignedMessage {
|
|
8
25
|
message: string;
|
|
9
26
|
signature: string;
|
|
@@ -63,6 +80,22 @@ export declare class SignatureService {
|
|
|
63
80
|
* Used for challenge-response authentication
|
|
64
81
|
*/
|
|
65
82
|
static signChallenge(challenge: string): Promise<AuthChallenge>;
|
|
83
|
+
/**
|
|
84
|
+
* Create a signed authentication challenge response using the SHARED identity
|
|
85
|
+
* key (the cross-app `group.so.oxy.shared` keychain key), not the primary
|
|
86
|
+
* device key.
|
|
87
|
+
*
|
|
88
|
+
* Mirrors {@link signChallenge} exactly — same message format
|
|
89
|
+
* (`auth:${publicKey}:${challenge}:${timestamp}`) so the server verification
|
|
90
|
+
* path is unchanged — but sources the shared public/private key from
|
|
91
|
+
* `KeyManager` and signs with `signWithKey`. Used by "Sign in with Oxy"
|
|
92
|
+
* same-device shared-keychain SSO (Mechanism A): a sibling native app proves
|
|
93
|
+
* control of the shared identity to mint its own session.
|
|
94
|
+
*
|
|
95
|
+
* Throws if no shared identity exists (native-only; the shared keychain is
|
|
96
|
+
* unavailable on web).
|
|
97
|
+
*/
|
|
98
|
+
static signChallengeWithSharedKey(challenge: string): Promise<AuthChallenge>;
|
|
66
99
|
/**
|
|
67
100
|
* Verify a challenge response
|
|
68
101
|
*/
|
|
@@ -86,5 +119,33 @@ export declare class SignatureService {
|
|
|
86
119
|
publicKey: string;
|
|
87
120
|
timestamp: number;
|
|
88
121
|
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Build a signed-record envelope for a self-issued identity/profile record.
|
|
124
|
+
*
|
|
125
|
+
* The envelope is self-issued: `issuer` equals `subject` (the signer's DID).
|
|
126
|
+
* The signature covers the canonical JSON of every field EXCEPT `publicKey`
|
|
127
|
+
* and `signature` (see {@link signedRecordSigningInput}); `alg` is
|
|
128
|
+
* `ES256K-DER-SHA256` (secp256k1 over the SHA-256 of the canonical bytes,
|
|
129
|
+
* DER-encoded), the same scheme this service uses everywhere else.
|
|
130
|
+
*
|
|
131
|
+
* Requires a stored identity (native secure storage); throws if none exists.
|
|
132
|
+
*
|
|
133
|
+
* @param type - The record category (`'identity'` or `'profile'`).
|
|
134
|
+
* @param subject - The subject DID the record is about (also the issuer).
|
|
135
|
+
* @param record - The arbitrary record payload to attest to.
|
|
136
|
+
*/
|
|
137
|
+
static signRecord(type: SignedRecordEnvelope['type'], subject: string, record: Record<string, unknown>): Promise<SignedRecordEnvelope>;
|
|
138
|
+
/**
|
|
139
|
+
* Verify a signed-record envelope: recompute the canonical signing input from
|
|
140
|
+
* the envelope's own fields and check the signature against the envelope's
|
|
141
|
+
* `publicKey`.
|
|
142
|
+
*
|
|
143
|
+
* Note: this confirms the signature is internally consistent with the
|
|
144
|
+
* embedded `publicKey`. It does NOT establish that `publicKey` is an
|
|
145
|
+
* authorized verification method for `subject` — that authorization check is
|
|
146
|
+
* the server's responsibility (it asserts the key is a current verification
|
|
147
|
+
* method on the subject's DID).
|
|
148
|
+
*/
|
|
149
|
+
static verifyRecord(envelope: SignedRecordEnvelope): Promise<boolean>;
|
|
89
150
|
}
|
|
90
151
|
export default SignatureService;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export type { SilentAuthOptions } from './mixins/OxyServices.silent';
|
|
|
30
30
|
export type { RedirectAuthOptions } from './mixins/OxyServices.redirect';
|
|
31
31
|
export { ServiceCredentialMismatchError } from './mixins/OxyServices.auth';
|
|
32
32
|
export type { ServiceTokenResponse } from './mixins/OxyServices.auth';
|
|
33
|
+
export type { CommonsSignInHandle, CommonsSignInStatus, CommonsApprovalInfo, CommonsSignInActionResult, } from './mixins/OxyServices.auth';
|
|
33
34
|
export type { ServiceApp, ServiceActingAsVerification } from './mixins/OxyServices.utility';
|
|
34
35
|
export type { CreateManagedAccountInput, ManagedAccountManager, ManagedAccount, } from './mixins/OxyServices.managedAccounts';
|
|
35
36
|
export type { ContactDiscoveryMatch, ContactDiscoveryResponse, } from './mixins/OxyServices.contacts';
|
|
@@ -41,6 +42,8 @@ export type { CanonicalUserHandleInput, UserHandleInput } from './utils/userHand
|
|
|
41
42
|
export type { Application, PublicApplication, ApplicationMember, ApplicationCredential, ApplicationRole, ApplicationType, ApplicationStatus, ApplicationMemberStatus, ApplicationCredentialType, ApplicationCredentialStatus, ApplicationEnvironment, CreateApplicationInput, UpdateApplicationInput, InviteApplicationMemberInput, UpdateApplicationMemberInput, TransferApplicationOwnershipInput, CreateApplicationCredentialInput, ApplicationCredentialWithSecret, RotateApplicationCredentialResult, ApplicationUsagePeriod, ApplicationUsageSummary, ApplicationUsageByDay, ApplicationUsageByEndpoint, ApplicationUsageStats, ApplicationSuccessResult, } from './mixins/OxyServices.applications';
|
|
42
43
|
export type { Workspace, WorkspaceMember, WorkspaceRole, WorkspaceType, WorkspaceStatus, WorkspaceMemberStatus, CreateWorkspaceInput, UpdateWorkspaceInput, InviteWorkspaceMemberInput, UpdateWorkspaceMemberInput, TransferWorkspaceOwnershipInput, WorkspaceSuccessResult, } from './mixins/OxyServices.workspaces';
|
|
43
44
|
export type { ReputationCategory, TrustTier, ReputationTransactionStatus, ReputationTargetEntityType, ReputationDisputeStatus, ReputationInfluenceContext, ReputationTransaction, ReputationBalanceBreakdown, ReputationInfluence, ReputationReliability, ReputationBalance, ReputationDispute, ReputationRule, ReputationLeaderboardEntry, ReputationInfluenceResult, ReverseReputationTransactionResult, AwardReputationInput, CreateReputationDisputeInput, ResolveReputationDisputeInput, UpsertReputationRuleInput, ReverseReputationTransactionInput, } from './mixins/OxyServices.reputation';
|
|
45
|
+
export { buildUserDid } from './mixins/OxyServices.identity';
|
|
46
|
+
export type { IdentityRecordType, UnlinkableAuthMethodType, LinkAuthMethodResult, PublishRecordResult, VerifyRecordResult, VerifyDomainResult, RemoveDomainResult, } from './mixins/OxyServices.identity';
|
|
44
47
|
export { SessionSyncRequiredError, AuthenticationFailedError, ensureValidToken, isAuthenticationError, withAuthErrorHandling, authenticatedApiCall, } from './utils/authHelpers';
|
|
45
48
|
export type { HandleApiErrorOptions } from './utils/authHelpers';
|
|
46
49
|
export { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual, } from './utils/sessionUtils';
|
|
@@ -48,8 +51,9 @@ export type { ClientSession, StorageKeys, MinimalUserData, SessionLoginResponse,
|
|
|
48
51
|
export type { RefreshAllResponse, RefreshAllAccount, RefreshAllAccountUser, RefreshCookieResponse, } from './models/interfaces';
|
|
49
52
|
export { KeyManager, IdentityAlreadyExistsError, IdentityPersistError, } from './crypto/keyManager';
|
|
50
53
|
export type { KeyPair } from './crypto/keyManager';
|
|
51
|
-
export { SignatureService } from './crypto/signatureService';
|
|
52
|
-
export type { SignedMessage, AuthChallenge } from './crypto/signatureService';
|
|
54
|
+
export { SignatureService, signedRecordSigningInput } from './crypto/signatureService';
|
|
55
|
+
export type { SignedMessage, AuthChallenge, SignedRecordSigningFields } from './crypto/signatureService';
|
|
56
|
+
export { canonicalize } from './crypto/canonicalJson';
|
|
53
57
|
export { RecoveryPhraseService } from './crypto/recoveryPhrase';
|
|
54
58
|
export type { RecoveryPhraseResult } from './crypto/recoveryPhrase';
|
|
55
59
|
export { DeviceManager } from './utils/deviceManager';
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { User, RefreshAllResponse, RefreshCookieResponse } from '../models/interfaces';
|
|
7
7
|
import type { SessionLoginResponse } from '../models/session';
|
|
8
8
|
import type { OxyServicesBase } from '../OxyServices.base';
|
|
9
|
+
import type { PublicApplication } from './OxyServices.applications';
|
|
9
10
|
export interface ChallengeResponse {
|
|
10
11
|
challenge: string;
|
|
11
12
|
expiresAt: string;
|
|
@@ -48,6 +49,60 @@ export interface PublicKeyCheckResponse {
|
|
|
48
49
|
registered: boolean;
|
|
49
50
|
message: string;
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Handle returned by {@link OxyServicesAuthMixin.startCommonsSignIn} for a
|
|
54
|
+
* relying-party app initiating a "Sign in with Oxy" flow.
|
|
55
|
+
*
|
|
56
|
+
* `sessionToken` is the SECRET, high-entropy device-flow credential — it stays
|
|
57
|
+
* on the initiating client, is exchanged once via `claimSessionByToken`, and is
|
|
58
|
+
* NEVER placed in the QR/deep-link. `authorizeCode` is the PUBLIC handle carried
|
|
59
|
+
* in `qrPayload`; the approver (Commons) resolves it via
|
|
60
|
+
* {@link OxyServicesAuthMixin.getCommonsApprovalInfo}.
|
|
61
|
+
*/
|
|
62
|
+
export interface CommonsSignInHandle {
|
|
63
|
+
/** Secret device-flow token (held by the initiator; exchanged via `claimSessionByToken`). */
|
|
64
|
+
sessionToken: string;
|
|
65
|
+
/** Public, single-use authorize code carried in the QR / deep-link. */
|
|
66
|
+
authorizeCode: string;
|
|
67
|
+
/** Ready-to-render deep-link / universal-link string (`oxycommons://approve?...`). */
|
|
68
|
+
qrPayload: string;
|
|
69
|
+
/** Server-authoritative expiry (epoch milliseconds). */
|
|
70
|
+
expiresAt: number;
|
|
71
|
+
/** Session lifecycle status as reported by the server (e.g. `'pending'`). */
|
|
72
|
+
status: string;
|
|
73
|
+
}
|
|
74
|
+
/** Poll result for a "Sign in with Oxy" device-flow session (`GET /auth/session/status`). */
|
|
75
|
+
export interface CommonsSignInStatus {
|
|
76
|
+
/** True once an approver has authorized the session. */
|
|
77
|
+
authorized: boolean;
|
|
78
|
+
/** The authorized session id (present once `authorized`). */
|
|
79
|
+
sessionId?: string;
|
|
80
|
+
/** The approving identity's public key (present once `authorized`). */
|
|
81
|
+
publicKey?: string;
|
|
82
|
+
/** Lifecycle status (`'pending'` | `'authorized'` | `'cancelled'` | `'expired'`). */
|
|
83
|
+
status?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Server-resolved approval context shown by the approver (Commons) before
|
|
87
|
+
* authorizing — the TRUSTED identity of the requesting app, resolved from the
|
|
88
|
+
* `authorizeCode` server-side (never from the QR string).
|
|
89
|
+
*/
|
|
90
|
+
export interface CommonsApprovalInfo {
|
|
91
|
+
/** Sanitized, display-safe identity of the requesting application. */
|
|
92
|
+
application: PublicApplication;
|
|
93
|
+
/** OAuth scopes the application is requesting. */
|
|
94
|
+
scopes: string[];
|
|
95
|
+
/** The origin the session is bound to (the RP web origin), when applicable. */
|
|
96
|
+
boundOrigin?: string;
|
|
97
|
+
/** Server-authoritative expiry (epoch milliseconds). */
|
|
98
|
+
expiresAt: number;
|
|
99
|
+
/** Session lifecycle status. */
|
|
100
|
+
status: string;
|
|
101
|
+
}
|
|
102
|
+
/** Result of approving / denying a "Sign in with Oxy" request. */
|
|
103
|
+
export interface CommonsSignInActionResult {
|
|
104
|
+
success: boolean;
|
|
105
|
+
}
|
|
51
106
|
export interface ServiceTokenResponse {
|
|
52
107
|
token: string;
|
|
53
108
|
expiresIn: number;
|
|
@@ -275,6 +330,87 @@ export declare function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(B
|
|
|
275
330
|
expiresAt: string;
|
|
276
331
|
user: User;
|
|
277
332
|
}>;
|
|
333
|
+
/**
|
|
334
|
+
* MECHANISM A — same-device shared-keychain SSO.
|
|
335
|
+
*
|
|
336
|
+
* Native-only. If this device holds a shared identity (the cross-app
|
|
337
|
+
* `group.so.oxy.shared` keychain key), prove control of it and mint a
|
|
338
|
+
* session: `requestChallenge(sharedPublicKey)` → `signChallengeWithSharedKey`
|
|
339
|
+
* → `verifyChallenge` (which plants the tokens). Returns `null` on web or
|
|
340
|
+
* when no shared identity is present — never throws for the absent-identity
|
|
341
|
+
* case, so a cold-boot caller can fall through to the next step.
|
|
342
|
+
*
|
|
343
|
+
* The cold-boot wiring that CALLS this lives in `OxyContext`
|
|
344
|
+
* (`@oxyhq/services`); this method just performs the exchange.
|
|
345
|
+
*/
|
|
346
|
+
signInWithSharedIdentity(opts?: {
|
|
347
|
+
deviceName?: string;
|
|
348
|
+
deviceFingerprint?: string;
|
|
349
|
+
}): Promise<SessionLoginResponse | null>;
|
|
350
|
+
/**
|
|
351
|
+
* MECHANISM B (relying party) — begin a "Sign in with Oxy" handoff.
|
|
352
|
+
*
|
|
353
|
+
* Generates a secret device-flow `sessionToken` client-side (it never
|
|
354
|
+
* appears in the QR), registers it with `POST /auth/session/create`, and
|
|
355
|
+
* returns the server-issued public `authorizeCode` + ready-to-render
|
|
356
|
+
* `qrPayload`. Render the QR (web) / open the deep-link (same-device); the
|
|
357
|
+
* approver resolves the code and authorizes. Then poll with
|
|
358
|
+
* {@link pollCommonsSignIn} and, on `authorized`, exchange the
|
|
359
|
+
* `sessionToken` via the existing `claimSessionByToken`.
|
|
360
|
+
*
|
|
361
|
+
* @param params.clientId - The RP's registered OAuth client id
|
|
362
|
+
* (ApplicationCredential publicKey); required so the server can resolve the
|
|
363
|
+
* requesting application's identity.
|
|
364
|
+
*/
|
|
365
|
+
startCommonsSignIn(params: {
|
|
366
|
+
clientId: string;
|
|
367
|
+
}): Promise<CommonsSignInHandle>;
|
|
368
|
+
/**
|
|
369
|
+
* MECHANISM B (relying party) — poll a device-flow session for approval.
|
|
370
|
+
*
|
|
371
|
+
* Backstop for the auth socket. On `authorized` (with a `sessionId`), the
|
|
372
|
+
* caller exchanges the secret `sessionToken` via the existing
|
|
373
|
+
* `claimSessionByToken` to mint the first access token.
|
|
374
|
+
*
|
|
375
|
+
* @param sessionToken - The secret token from {@link startCommonsSignIn}.
|
|
376
|
+
*/
|
|
377
|
+
pollCommonsSignIn(sessionToken: string): Promise<CommonsSignInStatus>;
|
|
378
|
+
/**
|
|
379
|
+
* MECHANISM B (approver / Commons) — resolve the TRUSTED identity of a
|
|
380
|
+
* sign-in request from its public `authorizeCode`.
|
|
381
|
+
*
|
|
382
|
+
* The returned `application` is resolved server-side and is the only safe
|
|
383
|
+
* thing to display in the approval UI — NEVER trust the app/name/origin
|
|
384
|
+
* strings carried in the QR payload. Public (no auth required).
|
|
385
|
+
*
|
|
386
|
+
* @param authorizeCode - The public code scanned from the QR / deep-link.
|
|
387
|
+
*/
|
|
388
|
+
getCommonsApprovalInfo(authorizeCode: string): Promise<CommonsApprovalInfo>;
|
|
389
|
+
/**
|
|
390
|
+
* MECHANISM B (approver / Commons) — approve a sign-in request by signing a
|
|
391
|
+
* fresh challenge with the PRIMARY local identity key.
|
|
392
|
+
*
|
|
393
|
+
* Commons holds the user's identity as its primary key (not the shared
|
|
394
|
+
* key), so this uses `signChallenge`. The signed-but-cookieless authorize
|
|
395
|
+
* endpoint resolves the user from the verified signer — the RP that started
|
|
396
|
+
* the flow then claims its session. Native-only (requires a local identity).
|
|
397
|
+
*
|
|
398
|
+
* @param params.authorizeCode - The public code being approved.
|
|
399
|
+
* @param params.deviceName - Optional human-readable device label.
|
|
400
|
+
* @param params.deviceFingerprint - Optional device fingerprint.
|
|
401
|
+
*/
|
|
402
|
+
approveCommonsSignIn(params: {
|
|
403
|
+
authorizeCode: string;
|
|
404
|
+
deviceName?: string;
|
|
405
|
+
deviceFingerprint?: string;
|
|
406
|
+
}): Promise<CommonsSignInActionResult>;
|
|
407
|
+
/**
|
|
408
|
+
* MECHANISM B (approver / Commons) — deny a sign-in request, cancelling the
|
|
409
|
+
* device-flow session so the RP stops waiting.
|
|
410
|
+
*
|
|
411
|
+
* @param authorizeCode - The public code being denied.
|
|
412
|
+
*/
|
|
413
|
+
denyCommonsSignIn(authorizeCode: string): Promise<CommonsSignInActionResult>;
|
|
278
414
|
/**
|
|
279
415
|
* Refresh every device-local refresh-cookie slot in a single round trip
|
|
280
416
|
* (Google-style multi-account rebuild).
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Methods Mixin (self-sovereign identity layer)
|
|
3
|
+
*
|
|
4
|
+
* Provides typed access to Oxy's AtProto/Bluesky-flavoured identity &
|
|
5
|
+
* portability layer:
|
|
6
|
+
* - DID resolution (`did:web:oxy.so:u:<userId>`, derived on demand by the API).
|
|
7
|
+
* - The auth-method ↔ DID verification-method mapping and its reversibility
|
|
8
|
+
* (link/unlink an identity key, link a password) via the existing
|
|
9
|
+
* `/auth/link` surface.
|
|
10
|
+
* - Signed records: clients sign an envelope with their own cryptographic key
|
|
11
|
+
* (`SignatureService.signRecord` + the shared `canonicalize`) and publish it;
|
|
12
|
+
* anyone can fetch and verify it.
|
|
13
|
+
* - The signed data-export ("credible exit") bundle.
|
|
14
|
+
* - Verified-domain badges (prove ownership of `nate.com`).
|
|
15
|
+
*
|
|
16
|
+
* Wire shapes come from `@oxyhq/contracts` (`DidDocument`,
|
|
17
|
+
* `SignedRecordEnvelope`, `AuthMethodsResponse`, `VerifiedDomain`,
|
|
18
|
+
* `DomainVerificationInstructions`, `ExportBundle`) — the single source of truth
|
|
19
|
+
* the API validates its output against, so producer and consumer cannot drift.
|
|
20
|
+
*
|
|
21
|
+
* Identity signing is NATIVE-ONLY: the private key lives in native secure
|
|
22
|
+
* storage, so `linkIdentityKey`, `signRecord`, and `publishRecord` require an
|
|
23
|
+
* on-device identity and throw on web (where `KeyManager.getPublicKey()` is
|
|
24
|
+
* always `null`).
|
|
25
|
+
*/
|
|
26
|
+
import type { AuthMethodsResponse, DidDocument, DomainVerificationInstructions, ExportBundle, SignedRecordEnvelope, VerifiedDomain } from '@oxyhq/contracts';
|
|
27
|
+
import type { OxyServicesBase } from '../OxyServices.base';
|
|
28
|
+
/** Record categories a client may sign and publish. */
|
|
29
|
+
export type IdentityRecordType = SignedRecordEnvelope['type'];
|
|
30
|
+
/** Auth-method types that can be unlinked via {@link OxyServicesIdentityMixin}. */
|
|
31
|
+
export type UnlinkableAuthMethodType = 'identity' | 'password' | 'google' | 'apple' | 'github';
|
|
32
|
+
/**
|
|
33
|
+
* Result of a link/unlink auth-method mutation (`POST /auth/link`,
|
|
34
|
+
* `DELETE /auth/link/:type`).
|
|
35
|
+
*/
|
|
36
|
+
export interface LinkAuthMethodResult {
|
|
37
|
+
success: boolean;
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Result of publishing a signed record (`POST /identity/records`). Echoes the
|
|
42
|
+
* stored envelope plus the server's verification verdict.
|
|
43
|
+
*/
|
|
44
|
+
export interface PublishRecordResult {
|
|
45
|
+
envelope: SignedRecordEnvelope;
|
|
46
|
+
verified: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Result of verifying a stored record (`GET /identity/records/:userId/:type/verify`).
|
|
50
|
+
* `verified` is the server's verdict; `reason` is present when it is `false`.
|
|
51
|
+
*/
|
|
52
|
+
export interface VerifyRecordResult {
|
|
53
|
+
verified: boolean;
|
|
54
|
+
reason?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Result of a successful domain verification (`POST /identity/domains/:domain/verify`). */
|
|
57
|
+
export interface VerifyDomainResult {
|
|
58
|
+
verified: boolean;
|
|
59
|
+
domain: VerifiedDomain;
|
|
60
|
+
}
|
|
61
|
+
/** Result of removing a verified domain (`DELETE /identity/domains/:domain`). */
|
|
62
|
+
export interface RemoveDomainResult {
|
|
63
|
+
success: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Derive a user's Oxy DID from their stable account id.
|
|
67
|
+
* `did:web:oxy.so:u:<userId>`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function buildUserDid(userId: string): string;
|
|
70
|
+
export declare function OxyServicesIdentityMixin<T extends typeof OxyServicesBase>(Base: T): {
|
|
71
|
+
new (...args: any[]): {
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the W3C DID document for any user. The API derives it on demand
|
|
74
|
+
* from the account's `authMethods` + `publicKey` — there is no stored
|
|
75
|
+
* document. Public (no auth required); short-TTL cached.
|
|
76
|
+
*
|
|
77
|
+
* @param userId - The account's Mongo `_id`. URL-encoded into the path.
|
|
78
|
+
*/
|
|
79
|
+
resolveDid(userId: string): Promise<DidDocument>;
|
|
80
|
+
/**
|
|
81
|
+
* The current user's DID (`did:web:oxy.so:u:<userId>`), derived locally from
|
|
82
|
+
* the access token's user id. Throws if no user is authenticated.
|
|
83
|
+
*/
|
|
84
|
+
getMyDid(): string;
|
|
85
|
+
/** Resolve the current user's DID document. Requires an authenticated session. */
|
|
86
|
+
getMyDidDocument(): Promise<DidDocument>;
|
|
87
|
+
/**
|
|
88
|
+
* List the current user's linked authentication methods plus their DID.
|
|
89
|
+
* Each `identity` method carries a `verificationMethodId` linking it to its
|
|
90
|
+
* DID verification-method fragment.
|
|
91
|
+
*/
|
|
92
|
+
listAuthMethods(): Promise<AuthMethodsResponse>;
|
|
93
|
+
/**
|
|
94
|
+
* Link the on-device cryptographic identity to the current account,
|
|
95
|
+
* upgrading it from custodial to self-sovereign. Signs a proof of private
|
|
96
|
+
* key ownership and posts it to `POST /auth/link`.
|
|
97
|
+
*
|
|
98
|
+
* NATIVE-ONLY: requires a stored identity (throws if `KeyManager` has no key
|
|
99
|
+
* or no user is authenticated). The signed payload is
|
|
100
|
+
* `JSON.stringify({ action: 'link_identity', userId, timestamp })` — the
|
|
101
|
+
* exact bytes the server reconstructs and verifies.
|
|
102
|
+
*/
|
|
103
|
+
linkIdentityKey(): Promise<LinkAuthMethodResult>;
|
|
104
|
+
/**
|
|
105
|
+
* Link password authentication to the current account. Adds a `password`
|
|
106
|
+
* auth method (does not remove existing methods).
|
|
107
|
+
*
|
|
108
|
+
* @param email - The email to associate with password auth.
|
|
109
|
+
* @param password - The new password (server enforces strength rules).
|
|
110
|
+
*/
|
|
111
|
+
linkPassword(email: string, password: string): Promise<LinkAuthMethodResult>;
|
|
112
|
+
/**
|
|
113
|
+
* Unlink an authentication method from the current account. The server
|
|
114
|
+
* refuses to remove the last remaining method (the account would become
|
|
115
|
+
* inaccessible). Unlinking `identity` downgrades the account to custodial.
|
|
116
|
+
*
|
|
117
|
+
* @param type - The auth-method type to remove.
|
|
118
|
+
*/
|
|
119
|
+
unlinkAuthMethod(type: UnlinkableAuthMethodType): Promise<LinkAuthMethodResult>;
|
|
120
|
+
/**
|
|
121
|
+
* Sign a record with the on-device identity key, WITHOUT publishing it.
|
|
122
|
+
* The subject is the current user's DID. NATIVE-ONLY (requires a stored
|
|
123
|
+
* key). Use {@link publishRecord} to sign and store in one step.
|
|
124
|
+
*
|
|
125
|
+
* @param type - The record category.
|
|
126
|
+
* @param record - The arbitrary record payload to attest to.
|
|
127
|
+
*/
|
|
128
|
+
signRecord(type: IdentityRecordType, record: Record<string, unknown>): Promise<SignedRecordEnvelope>;
|
|
129
|
+
/**
|
|
130
|
+
* Sign a record and publish it to the append-only record store
|
|
131
|
+
* (`POST /identity/records`). NATIVE-ONLY (requires a stored key).
|
|
132
|
+
*
|
|
133
|
+
* @param type - The record category.
|
|
134
|
+
* @param record - The arbitrary record payload to attest to.
|
|
135
|
+
*/
|
|
136
|
+
publishRecord(type: IdentityRecordType, record: Record<string, unknown>): Promise<PublishRecordResult>;
|
|
137
|
+
/**
|
|
138
|
+
* Fetch a user's most recent signed record of a given type. Public (no auth
|
|
139
|
+
* required); short-TTL cached.
|
|
140
|
+
*
|
|
141
|
+
* @param userId - The subject account's Mongo `_id`.
|
|
142
|
+
* @param type - The record category to fetch.
|
|
143
|
+
*/
|
|
144
|
+
getRecord(userId: string, type: IdentityRecordType): Promise<SignedRecordEnvelope>;
|
|
145
|
+
/**
|
|
146
|
+
* Ask the server to verify a user's stored record: it recomputes the
|
|
147
|
+
* canonical signing input, checks the signature, and asserts the signing key
|
|
148
|
+
* is a current verification method on the subject's DID.
|
|
149
|
+
*
|
|
150
|
+
* @param userId - The subject account's Mongo `_id`.
|
|
151
|
+
* @param type - The record category to verify.
|
|
152
|
+
*/
|
|
153
|
+
verifyRecord(userId: string, type: IdentityRecordType): Promise<VerifyRecordResult>;
|
|
154
|
+
/**
|
|
155
|
+
* Download the current user's signed, open-format data-export bundle
|
|
156
|
+
* (`GET /users/me/export`) — the "credible exit" snapshot. Always carries an
|
|
157
|
+
* Oxy provenance `attestation`; carries an optional client `proof` when the
|
|
158
|
+
* account holds its own key.
|
|
159
|
+
*/
|
|
160
|
+
exportMyData(): Promise<ExportBundle>;
|
|
161
|
+
/**
|
|
162
|
+
* Start verifying ownership of a domain. Returns the instructions: publish
|
|
163
|
+
* EITHER the DNS-TXT record OR the `/.well-known/oxy-domain` file, then call
|
|
164
|
+
* {@link verifyDomain}.
|
|
165
|
+
*
|
|
166
|
+
* @param domain - The domain to claim (e.g. `nate.com`).
|
|
167
|
+
*/
|
|
168
|
+
requestDomainVerification(domain: string): Promise<DomainVerificationInstructions>;
|
|
169
|
+
/**
|
|
170
|
+
* Complete domain verification: the server checks the DNS-TXT record or
|
|
171
|
+
* well-known file and, on success, attaches the domain to the account
|
|
172
|
+
* (surfaced in the DID's `alsoKnownAs` and the user's `verifiedDomains`).
|
|
173
|
+
*
|
|
174
|
+
* @param domain - The domain previously requested via
|
|
175
|
+
* {@link requestDomainVerification}.
|
|
176
|
+
*/
|
|
177
|
+
verifyDomain(domain: string): Promise<VerifyDomainResult>;
|
|
178
|
+
/** List the current user's verified domains. */
|
|
179
|
+
listDomains(): Promise<VerifiedDomain[]>;
|
|
180
|
+
/**
|
|
181
|
+
* Remove a verified domain from the current account.
|
|
182
|
+
* @param domain - The verified domain to remove.
|
|
183
|
+
*/
|
|
184
|
+
removeDomain(domain: string): Promise<RemoveDomainResult>;
|
|
185
|
+
/**
|
|
186
|
+
* Bust the cached reads that an identity mutation invalidates: the current
|
|
187
|
+
* user (`/users/me*`), the linked auth-methods list, the verified-domains
|
|
188
|
+
* list, and the user's derived DID document (which embeds auth methods +
|
|
189
|
+
* verified domains, so it goes stale on link/unlink/domain changes).
|
|
190
|
+
*
|
|
191
|
+
* Internal helper (leading underscore); not part of the supported public
|
|
192
|
+
* surface. Public rather than `private` because mixins compose into an
|
|
193
|
+
* exported anonymous class, where TypeScript cannot represent a private
|
|
194
|
+
* member in the emitted declaration file (TS4094).
|
|
195
|
+
*/
|
|
196
|
+
_invalidateIdentityCaches(userId: string | null): void;
|
|
197
|
+
httpService: import("../HttpService").HttpService;
|
|
198
|
+
cloudURL: string;
|
|
199
|
+
config: import("../OxyServices.base").OxyConfig;
|
|
200
|
+
__resetTokensForTests(): void;
|
|
201
|
+
makeRequest<T_1>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", url: string, data?: any, options?: import("../HttpService").RequestOptions): Promise<T_1>;
|
|
202
|
+
getBaseURL(): string;
|
|
203
|
+
getSessionBaseUrl(): string;
|
|
204
|
+
getClient(): import("../HttpService").HttpService;
|
|
205
|
+
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
206
|
+
getMetrics(): {
|
|
207
|
+
totalRequests: number;
|
|
208
|
+
successfulRequests: number;
|
|
209
|
+
failedRequests: number;
|
|
210
|
+
cacheHits: number;
|
|
211
|
+
cacheMisses: number;
|
|
212
|
+
averageResponseTime: number;
|
|
213
|
+
};
|
|
214
|
+
clearCache(): void;
|
|
215
|
+
clearCacheEntry(key: string): void;
|
|
216
|
+
clearCacheByPrefix(prefix: string): number;
|
|
217
|
+
getCacheStats(): {
|
|
218
|
+
size: number;
|
|
219
|
+
hits: number;
|
|
220
|
+
misses: number;
|
|
221
|
+
hitRate: number;
|
|
222
|
+
};
|
|
223
|
+
getCloudURL(): string;
|
|
224
|
+
setTokens(accessToken: string): void;
|
|
225
|
+
clearTokens(): void;
|
|
226
|
+
onTokensChanged(listener: (accessToken: string | null) => void): () => void;
|
|
227
|
+
_cachedUserId: string | null | undefined;
|
|
228
|
+
_cachedAccessToken: string | null;
|
|
229
|
+
getCurrentUserId(): string | null;
|
|
230
|
+
hasValidToken(): boolean;
|
|
231
|
+
getAccessToken(): string | null;
|
|
232
|
+
setActingAs(userId: string | null): void;
|
|
233
|
+
getActingAs(): string | null;
|
|
234
|
+
waitForAuth(timeoutMs?: number): Promise<boolean>;
|
|
235
|
+
withAuthRetry<T_1>(operation: () => Promise<T_1>, operationName: string, options?: {
|
|
236
|
+
maxRetries?: number;
|
|
237
|
+
retryDelay?: number;
|
|
238
|
+
authTimeoutMs?: number;
|
|
239
|
+
}): Promise<T_1>;
|
|
240
|
+
validate(): Promise<boolean>;
|
|
241
|
+
handleError(error: unknown): Error;
|
|
242
|
+
healthCheck(): Promise<{
|
|
243
|
+
status: string;
|
|
244
|
+
users?: number;
|
|
245
|
+
timestamp?: string;
|
|
246
|
+
[key: string]: any;
|
|
247
|
+
}>;
|
|
248
|
+
};
|
|
249
|
+
} & T;
|
|
@@ -53,9 +53,12 @@ export declare function OxyServicesSsoMixin<T extends typeof OxyServicesBase>(Ba
|
|
|
53
53
|
* @param code - The opaque single-use code delivered in the SSO return
|
|
54
54
|
* fragment (see {@link parseSsoReturnFragment}). The central store burns
|
|
55
55
|
* it atomically on exchange.
|
|
56
|
+
* @param state - The state value returned alongside the code. In browsers,
|
|
57
|
+
* when an SSO bounce state is still stored for the current origin, this
|
|
58
|
+
* must match before any token-committing exchange is attempted.
|
|
56
59
|
* @returns The resolved {@link SessionLoginResponse}.
|
|
57
60
|
*/
|
|
58
|
-
exchangeSsoCode(code: string): Promise<SessionLoginResponse>;
|
|
61
|
+
exchangeSsoCode(code: string, state?: string): Promise<SessionLoginResponse>;
|
|
59
62
|
httpService: import("../HttpService").HttpService;
|
|
60
63
|
cloudURL: string;
|
|
61
64
|
config: import("../OxyServices.base").OxyConfig;
|
|
@@ -11,6 +11,7 @@ import { OxyServicesSilentAuthMixin } from './OxyServices.silent';
|
|
|
11
11
|
import { OxyServicesRedirectAuthMixin } from './OxyServices.redirect';
|
|
12
12
|
import { OxyServicesSsoMixin } from './OxyServices.sso';
|
|
13
13
|
import { OxyServicesUserMixin } from './OxyServices.user';
|
|
14
|
+
import { OxyServicesIdentityMixin } from './OxyServices.identity';
|
|
14
15
|
import { OxyServicesPrivacyMixin } from './OxyServices.privacy';
|
|
15
16
|
import { OxyServicesLanguageMixin } from './OxyServices.language';
|
|
16
17
|
import { OxyServicesPaymentMixin } from './OxyServices.payment';
|
|
@@ -37,7 +38,7 @@ import { OxyServicesAppDataMixin } from './OxyServices.appData';
|
|
|
37
38
|
* If you add a new mixin to `MIXIN_PIPELINE`, add it here too so its methods
|
|
38
39
|
* are visible without a cast.
|
|
39
40
|
*/
|
|
40
|
-
type AllMixinInstances = InstanceType<ReturnType<typeof OxyServicesAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesFedCMMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSilentAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesRedirectAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSsoMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesUserMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPrivacyMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesLanguageMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPaymentMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesReputationMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAssetsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesApplicationsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesWorkspacesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesLocationMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAnalyticsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesDevicesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSecurityMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesFeaturesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesTopicsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesManagedAccountsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesContactsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAppDataMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesUtilityMixin<typeof OxyServicesBase>>>;
|
|
41
|
+
type AllMixinInstances = InstanceType<ReturnType<typeof OxyServicesAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesFedCMMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSilentAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesRedirectAuthMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSsoMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesUserMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesIdentityMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPrivacyMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesLanguageMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesPaymentMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesReputationMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAssetsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesApplicationsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesWorkspacesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesLocationMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAnalyticsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesDevicesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesSecurityMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesFeaturesMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesTopicsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesManagedAccountsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesContactsMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesAppDataMixin<typeof OxyServicesBase>>> & InstanceType<ReturnType<typeof OxyServicesUtilityMixin<typeof OxyServicesBase>>>;
|
|
41
42
|
/**
|
|
42
43
|
* Constructor type for the fully composed mixin pipeline. Each mixin returns
|
|
43
44
|
* a new constructor that augments its input; reducing across the pipeline
|