@ankhorage/contracts 2.1.0 → 3.0.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ankhorage/contracts
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - d46f70b: Replace the optional URL-only OAuth adapter methods with one canonical provider-neutral OAuth capability that requires authorization start and callback completion, models transport cancellation and failures explicitly, and resolves successful OAuth sign-in to the existing `AuthSession` contract.
8
+
3
9
  ## 2.1.0
4
10
 
5
11
  ### Minor Changes
package/dist/auth.d.ts CHANGED
@@ -42,7 +42,6 @@ export interface AuthOAuthProviderConfig {
42
42
  label?: string;
43
43
  enabled?: boolean;
44
44
  scopes?: string[];
45
- redirectTo?: string;
46
45
  queryParams?: Record<string, string>;
47
46
  icon?: IconSpec;
48
47
  /** Logical server-side secret reference; raw credentials must never be stored here. */
@@ -120,20 +119,83 @@ export interface VerifyOtpInput {
120
119
  redirectTo?: string;
121
120
  metadata?: Record<string, unknown>;
122
121
  }
123
- export interface SignInWithOAuthInput {
122
+ export declare const AUTH_OAUTH_ERROR_STAGES: readonly ["start", "transport", "callback", "exchange", "session", "profile"];
123
+ export type AuthOAuthErrorStage = (typeof AUTH_OAUTH_ERROR_STAGES)[number];
124
+ export declare const AUTH_OAUTH_ERROR_CODES: readonly ["oauth_unavailable", "provider_disabled", "provider_misconfigured", "invalid_redirect_uri", "authorization_failed", "authorization_attempt_not_found", "invalid_callback", "state_mismatch", "pkce_mismatch", "callback_already_completed", "code_exchange_failed", "network_error", "session_persistence_failed", "profile_creation_failed", "provider_error"];
125
+ export type AuthOAuthErrorCode = (typeof AUTH_OAUTH_ERROR_CODES)[number];
126
+ export interface AuthOAuthError extends AuthAdapterError {
127
+ code: AuthOAuthErrorCode;
128
+ stage: AuthOAuthErrorStage;
129
+ provider?: AuthOAuthProviderId;
130
+ recoverable: boolean;
131
+ }
132
+ export declare const AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS: readonly ["user_cancelled", "browser_dismissed"];
133
+ export type AuthOAuthTransportCancellationReason = (typeof AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS)[number];
134
+ export declare const AUTH_OAUTH_CANCELLATION_REASONS: readonly ["user_cancelled", "browser_dismissed", "provider_denied"];
135
+ export type AuthOAuthCancellationReason = (typeof AUTH_OAUTH_CANCELLATION_REASONS)[number];
136
+ export declare const AUTH_OAUTH_TRANSPORT_ERROR_CODES: readonly ["browser_unavailable", "transport_failed"];
137
+ export type AuthOAuthTransportErrorCode = (typeof AUTH_OAUTH_TRANSPORT_ERROR_CODES)[number];
138
+ export interface AuthOAuthTransportError {
139
+ code: AuthOAuthTransportErrorCode;
140
+ message: string;
141
+ cause?: unknown;
142
+ }
143
+ export interface StartOAuthAuthorizationInput {
124
144
  provider: AuthOAuthProviderId;
125
- redirectTo?: string;
126
- scopes?: string[];
127
- queryParams?: Record<string, string>;
128
- metadata?: Record<string, unknown>;
145
+ redirectUri: string;
146
+ scopes?: readonly string[];
147
+ queryParams?: Readonly<Record<string, string>>;
129
148
  }
130
- export interface AuthOAuthRedirect {
149
+ export interface AuthOAuthAuthorizationRequest {
150
+ attemptId: string;
131
151
  provider: AuthOAuthProviderId;
132
- url: string;
152
+ authorizationUrl: string;
153
+ redirectUri: string;
133
154
  }
134
- export interface CompleteOAuthSignInInput {
155
+ export type AuthOAuthStartResult = {
156
+ ok: true;
157
+ data: AuthOAuthAuthorizationRequest;
158
+ } | {
159
+ ok: false;
160
+ error: AuthOAuthError;
161
+ };
162
+ export type AuthOAuthAuthorizationResponse = {
163
+ type: 'callback';
135
164
  url: string;
136
- redirectTo?: string;
165
+ } | {
166
+ type: 'cancelled';
167
+ reason: AuthOAuthTransportCancellationReason;
168
+ } | {
169
+ type: 'error';
170
+ error: AuthOAuthTransportError;
171
+ };
172
+ export interface CompleteOAuthAuthorizationInput {
173
+ attemptId: string;
174
+ response: AuthOAuthAuthorizationResponse;
175
+ }
176
+ export type AuthOAuthCompletionResult = {
177
+ ok: true;
178
+ status: 'authenticated';
179
+ provider: AuthOAuthProviderId;
180
+ session: AuthSession;
181
+ } | {
182
+ ok: false;
183
+ status: 'cancelled';
184
+ provider: AuthOAuthProviderId;
185
+ reason: AuthOAuthCancellationReason;
186
+ } | {
187
+ ok: false;
188
+ status: 'error';
189
+ error: AuthOAuthError;
190
+ };
191
+ export interface AuthOAuthCapabilities {
192
+ /** Enabled providers for which start and callback completion are operational. */
193
+ providers: readonly [AuthOAuthProviderId, ...AuthOAuthProviderId[]];
194
+ }
195
+ export interface AuthOAuthAdapter {
196
+ readonly capabilities: AuthOAuthCapabilities;
197
+ startAuthorization(input: StartOAuthAuthorizationInput): Promise<AuthOAuthStartResult>;
198
+ completeAuthorization(input: CompleteOAuthAuthorizationInput): Promise<AuthOAuthCompletionResult>;
137
199
  }
138
200
  export interface AuthAdapterCapabilities {
139
201
  signInIdentifiers: AuthIdentifierKind[];
@@ -141,11 +203,14 @@ export interface AuthAdapterCapabilities {
141
203
  supportsPasswordReset: boolean;
142
204
  supportsOtp: boolean;
143
205
  supportsSessionRefresh: boolean;
144
- supportsOAuth?: boolean;
145
- oauthProviders?: AuthOAuthProviderId[];
146
206
  }
147
207
  export interface AuthAdapter {
148
208
  readonly capabilities?: AuthAdapterCapabilities;
209
+ /**
210
+ * Presence is the canonical OAuth capability signal. When present, both authorization start and
211
+ * callback completion are mandatory and operational for every advertised provider.
212
+ */
213
+ readonly oauth?: AuthOAuthAdapter;
149
214
  signIn(input: SignInInput): Promise<AuthResult<AuthSession>>;
150
215
  signUp(input: SignUpInput): Promise<AuthResult<AuthSession | AuthUser>>;
151
216
  signOut(input?: SignOutInput): Promise<AuthResult>;
@@ -153,7 +218,5 @@ export interface AuthAdapter {
153
218
  refreshSession?(): Promise<AuthResult<AuthSession | null>>;
154
219
  requestPasswordReset?(input: PasswordResetInput): Promise<AuthResult>;
155
220
  verifyOtp?(input: VerifyOtpInput): Promise<AuthResult<AuthSession>>;
156
- signInWithOAuth?(input: SignInWithOAuthInput): Promise<AuthResult<AuthOAuthRedirect>>;
157
- completeOAuthSignIn?(input: CompleteOAuthSignInInput): Promise<AuthResult<AuthSession>>;
158
221
  }
159
222
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,eAAO,MAAM,qBAAqB,yCAA0C,CAAC;AAC7E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,eAAO,MAAM,mBAAmB,6FAMtB,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACxE,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEnE,eAAO,MAAM,uBAAuB,8MAoB1B,CAAC;AACX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAChF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,iBAAiB;;;;;;;CAOK,CAAC;AAEpC,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,cAAc,CAErE;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,mBAAmB,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,uFAAuF;IACvF,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,uBAAuB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,aAAa,CAAC,EAAE;QACd,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,UAAU,CAAC,KAAK,GAAG,IAAI,IAC/B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEN,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,cAAc,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,cAAc,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;IACxC,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,uBAAuB,CAAC;IAEhD,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC;IACxE,OAAO,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEnD,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;IACtD,cAAc,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;IAE3D,oBAAoB,CAAC,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtE,SAAS,CAAC,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAEpE,eAAe,CAAC,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACtF,mBAAmB,CAAC,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;CACzF"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/auth.js CHANGED
@@ -38,4 +38,41 @@ export const DEFAULT_AUTH_FLOW = {
38
38
  export function resolveAuthFlow(flow) {
39
39
  return { ...(flow ?? DEFAULT_AUTH_FLOW) };
40
40
  }
41
+ export const AUTH_OAUTH_ERROR_STAGES = [
42
+ 'start',
43
+ 'transport',
44
+ 'callback',
45
+ 'exchange',
46
+ 'session',
47
+ 'profile',
48
+ ];
49
+ export const AUTH_OAUTH_ERROR_CODES = [
50
+ 'oauth_unavailable',
51
+ 'provider_disabled',
52
+ 'provider_misconfigured',
53
+ 'invalid_redirect_uri',
54
+ 'authorization_failed',
55
+ 'authorization_attempt_not_found',
56
+ 'invalid_callback',
57
+ 'state_mismatch',
58
+ 'pkce_mismatch',
59
+ 'callback_already_completed',
60
+ 'code_exchange_failed',
61
+ 'network_error',
62
+ 'session_persistence_failed',
63
+ 'profile_creation_failed',
64
+ 'provider_error',
65
+ ];
66
+ export const AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS = [
67
+ 'user_cancelled',
68
+ 'browser_dismissed',
69
+ ];
70
+ export const AUTH_OAUTH_CANCELLATION_REASONS = [
71
+ ...AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS,
72
+ 'provider_denied',
73
+ ];
74
+ export const AUTH_OAUTH_TRANSPORT_ERROR_CODES = [
75
+ 'browser_unavailable',
76
+ 'transport_failed',
77
+ ];
41
78
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAG7E,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,qBAAqB;IACxB,UAAU;IACV,aAAa;IACb,WAAW;IACX,UAAU;CACF,CAAC;AAIX,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO;IACP,OAAO;IACP,WAAW;IACX,SAAS;IACT,UAAU;IACV,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,UAAU;IACV,UAAU;IACV,QAAQ;IACR,OAAO;IACP,SAAS;IACT,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,MAAM;CACE,CAAC;AAmBX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,SAAS;IACtB,WAAW,EAAE,SAAS;IACtB,YAAY,EAAE,UAAU;IACxB,mBAAmB,EAAE,iBAAiB;IACtC,eAAe,EAAE,GAAG;IACpB,iBAAiB,EAAE,SAAS;CACK,CAAC;AAEpC,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,iBAAiB,CAAC,EAAE,CAAC;AAC5C,CAAC","sourcesContent":["import type { SecretRef } from './secrets';\nimport type { IconSpec } from './types';\n\nexport const AUTH_IDENTIFIER_KINDS = ['email', 'phone', 'username'] as const;\nexport type AuthIdentifierKind = (typeof AUTH_IDENTIFIER_KINDS)[number];\n\nexport const AUTH_SIGN_UP_FIELDS = [\n ...AUTH_IDENTIFIER_KINDS,\n 'password',\n 'displayName',\n 'firstName',\n 'lastName',\n] as const;\nexport type KnownAuthSignUpField = (typeof AUTH_SIGN_UP_FIELDS)[number];\nexport type AuthSignUpField = KnownAuthSignUpField | (string & {});\n\nexport const AUTH_OAUTH_PROVIDER_IDS = [\n 'apple',\n 'azure',\n 'bitbucket',\n 'discord',\n 'facebook',\n 'figma',\n 'github',\n 'gitlab',\n 'google',\n 'kakao',\n 'keycloak',\n 'linkedin',\n 'notion',\n 'slack',\n 'spotify',\n 'twitch',\n 'twitter',\n 'workos',\n 'zoom',\n] as const;\nexport type KnownAuthOAuthProviderId = (typeof AUTH_OAUTH_PROVIDER_IDS)[number];\nexport type AuthOAuthProviderId = KnownAuthOAuthProviderId | (string & {});\n\nexport interface AuthIdentifier {\n kind: AuthIdentifierKind;\n value: string;\n}\n\nexport interface AuthFlowConfig {\n signInRoute: string;\n signUpRoute?: string;\n signOutRoute?: string;\n forgotPasswordRoute?: string;\n otpRoute?: string;\n postSignInRoute: string;\n unauthorizedRoute?: string;\n}\n\nexport const DEFAULT_AUTH_FLOW = {\n signInRoute: 'sign-in',\n signUpRoute: 'sign-up',\n signOutRoute: 'sign-out',\n forgotPasswordRoute: 'forgot-password',\n postSignInRoute: '/',\n unauthorizedRoute: 'sign-in',\n} as const satisfies AuthFlowConfig;\n\nexport function resolveAuthFlow(flow?: AuthFlowConfig): AuthFlowConfig {\n return { ...(flow ?? DEFAULT_AUTH_FLOW) };\n}\n\nexport interface AuthSignInConfig {\n identifiers: AuthIdentifierKind[];\n}\n\nexport interface AuthSignUpConfig {\n requiredFields: AuthSignUpField[];\n optionalFields?: AuthSignUpField[];\n}\n\nexport interface AuthOAuthProviderConfig {\n id: AuthOAuthProviderId;\n label?: string;\n enabled?: boolean;\n scopes?: string[];\n redirectTo?: string;\n queryParams?: Record<string, string>;\n icon?: IconSpec;\n /** Logical server-side secret reference; raw credentials must never be stored here. */\n credentialsRef?: SecretRef;\n}\n\nexport interface AuthOAuthConfig {\n enabled: boolean;\n callbackRoute: string;\n providers: AuthOAuthProviderConfig[];\n}\n\nexport interface AuthProviderConfig {\n provider: string;\n signIn: AuthSignInConfig;\n signUp?: AuthSignUpConfig;\n oauth?: AuthOAuthConfig;\n passwordReset?: {\n enabled: boolean;\n };\n otp?: {\n enabled: boolean;\n };\n}\n\nexport interface AuthUser {\n id: string;\n email?: string;\n phone?: string;\n username?: string;\n displayName?: string;\n avatarUrl?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AuthSession {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n tokenType?: string;\n user: AuthUser;\n}\n\nexport interface AuthAdapterError {\n code: string;\n message: string;\n cause?: unknown;\n}\n\nexport type AuthResult<TData = void> =\n | {\n ok: true;\n data?: TData;\n }\n | {\n ok: false;\n error: AuthAdapterError;\n };\n\nexport interface SignInInput {\n identifier: AuthIdentifier;\n password?: string;\n otp?: string;\n redirectTo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SignUpInput {\n identifier: AuthIdentifier;\n password?: string;\n profile?: Record<string, unknown>;\n redirectTo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SignOutInput {\n allDevices?: boolean;\n}\n\nexport interface PasswordResetInput {\n identifier: AuthIdentifier;\n redirectTo?: string;\n}\n\nexport interface VerifyOtpInput {\n identifier: AuthIdentifier;\n token: string;\n redirectTo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SignInWithOAuthInput {\n provider: AuthOAuthProviderId;\n redirectTo?: string;\n scopes?: string[];\n queryParams?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AuthOAuthRedirect {\n provider: AuthOAuthProviderId;\n url: string;\n}\n\nexport interface CompleteOAuthSignInInput {\n url: string;\n redirectTo?: string;\n}\n\nexport interface AuthAdapterCapabilities {\n signInIdentifiers: AuthIdentifierKind[];\n supportsSignUp: boolean;\n supportsPasswordReset: boolean;\n supportsOtp: boolean;\n supportsSessionRefresh: boolean;\n supportsOAuth?: boolean;\n oauthProviders?: AuthOAuthProviderId[];\n}\n\nexport interface AuthAdapter {\n readonly capabilities?: AuthAdapterCapabilities;\n\n signIn(input: SignInInput): Promise<AuthResult<AuthSession>>;\n signUp(input: SignUpInput): Promise<AuthResult<AuthSession | AuthUser>>;\n signOut(input?: SignOutInput): Promise<AuthResult>;\n\n getSession(): Promise<AuthResult<AuthSession | null>>;\n refreshSession?(): Promise<AuthResult<AuthSession | null>>;\n\n requestPasswordReset?(input: PasswordResetInput): Promise<AuthResult>;\n verifyOtp?(input: VerifyOtpInput): Promise<AuthResult<AuthSession>>;\n\n signInWithOAuth?(input: SignInWithOAuthInput): Promise<AuthResult<AuthOAuthRedirect>>;\n completeOAuthSignIn?(input: CompleteOAuthSignInInput): Promise<AuthResult<AuthSession>>;\n}\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAG7E,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,qBAAqB;IACxB,UAAU;IACV,aAAa;IACb,WAAW;IACX,UAAU;CACF,CAAC;AAIX,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO;IACP,OAAO;IACP,WAAW;IACX,SAAS;IACT,UAAU;IACV,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,UAAU;IACV,UAAU;IACV,QAAQ;IACR,OAAO;IACP,SAAS;IACT,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,MAAM;CACE,CAAC;AAmBX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,SAAS;IACtB,WAAW,EAAE,SAAS;IACtB,YAAY,EAAE,UAAU;IACxB,mBAAmB,EAAE,iBAAiB;IACtC,eAAe,EAAE,GAAG;IACpB,iBAAiB,EAAE,SAAS;CACK,CAAC;AAEpC,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,OAAO,EAAE,GAAG,CAAC,IAAI,IAAI,iBAAiB,CAAC,EAAE,CAAC;AAC5C,CAAC;AA2GD,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO;IACP,WAAW;IACX,UAAU;IACV,UAAU;IACV,SAAS;IACT,SAAS;CACD,CAAC;AAGX,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,mBAAmB;IACnB,mBAAmB;IACnB,wBAAwB;IACxB,sBAAsB;IACtB,sBAAsB;IACtB,iCAAiC;IACjC,kBAAkB;IAClB,gBAAgB;IAChB,eAAe;IACf,4BAA4B;IAC5B,sBAAsB;IACtB,eAAe;IACf,4BAA4B;IAC5B,yBAAyB;IACzB,gBAAgB;CACR,CAAC;AAUX,MAAM,CAAC,MAAM,yCAAyC,GAAG;IACvD,gBAAgB;IAChB,mBAAmB;CACX,CAAC;AAIX,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,GAAG,yCAAyC;IAC5C,iBAAiB;CACT,CAAC;AAGX,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,qBAAqB;IACrB,kBAAkB;CACV,CAAC","sourcesContent":["import type { SecretRef } from './secrets';\nimport type { IconSpec } from './types';\n\nexport const AUTH_IDENTIFIER_KINDS = ['email', 'phone', 'username'] as const;\nexport type AuthIdentifierKind = (typeof AUTH_IDENTIFIER_KINDS)[number];\n\nexport const AUTH_SIGN_UP_FIELDS = [\n ...AUTH_IDENTIFIER_KINDS,\n 'password',\n 'displayName',\n 'firstName',\n 'lastName',\n] as const;\nexport type KnownAuthSignUpField = (typeof AUTH_SIGN_UP_FIELDS)[number];\nexport type AuthSignUpField = KnownAuthSignUpField | (string & {});\n\nexport const AUTH_OAUTH_PROVIDER_IDS = [\n 'apple',\n 'azure',\n 'bitbucket',\n 'discord',\n 'facebook',\n 'figma',\n 'github',\n 'gitlab',\n 'google',\n 'kakao',\n 'keycloak',\n 'linkedin',\n 'notion',\n 'slack',\n 'spotify',\n 'twitch',\n 'twitter',\n 'workos',\n 'zoom',\n] as const;\nexport type KnownAuthOAuthProviderId = (typeof AUTH_OAUTH_PROVIDER_IDS)[number];\nexport type AuthOAuthProviderId = KnownAuthOAuthProviderId | (string & {});\n\nexport interface AuthIdentifier {\n kind: AuthIdentifierKind;\n value: string;\n}\n\nexport interface AuthFlowConfig {\n signInRoute: string;\n signUpRoute?: string;\n signOutRoute?: string;\n forgotPasswordRoute?: string;\n otpRoute?: string;\n postSignInRoute: string;\n unauthorizedRoute?: string;\n}\n\nexport const DEFAULT_AUTH_FLOW = {\n signInRoute: 'sign-in',\n signUpRoute: 'sign-up',\n signOutRoute: 'sign-out',\n forgotPasswordRoute: 'forgot-password',\n postSignInRoute: '/',\n unauthorizedRoute: 'sign-in',\n} as const satisfies AuthFlowConfig;\n\nexport function resolveAuthFlow(flow?: AuthFlowConfig): AuthFlowConfig {\n return { ...(flow ?? DEFAULT_AUTH_FLOW) };\n}\n\nexport interface AuthSignInConfig {\n identifiers: AuthIdentifierKind[];\n}\n\nexport interface AuthSignUpConfig {\n requiredFields: AuthSignUpField[];\n optionalFields?: AuthSignUpField[];\n}\n\nexport interface AuthOAuthProviderConfig {\n id: AuthOAuthProviderId;\n label?: string;\n enabled?: boolean;\n scopes?: string[];\n queryParams?: Record<string, string>;\n icon?: IconSpec;\n /** Logical server-side secret reference; raw credentials must never be stored here. */\n credentialsRef?: SecretRef;\n}\n\nexport interface AuthOAuthConfig {\n enabled: boolean;\n callbackRoute: string;\n providers: AuthOAuthProviderConfig[];\n}\n\nexport interface AuthProviderConfig {\n provider: string;\n signIn: AuthSignInConfig;\n signUp?: AuthSignUpConfig;\n oauth?: AuthOAuthConfig;\n passwordReset?: {\n enabled: boolean;\n };\n otp?: {\n enabled: boolean;\n };\n}\n\nexport interface AuthUser {\n id: string;\n email?: string;\n phone?: string;\n username?: string;\n displayName?: string;\n avatarUrl?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface AuthSession {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n tokenType?: string;\n user: AuthUser;\n}\n\nexport interface AuthAdapterError {\n code: string;\n message: string;\n cause?: unknown;\n}\n\nexport type AuthResult<TData = void> =\n | {\n ok: true;\n data?: TData;\n }\n | {\n ok: false;\n error: AuthAdapterError;\n };\n\nexport interface SignInInput {\n identifier: AuthIdentifier;\n password?: string;\n otp?: string;\n redirectTo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SignUpInput {\n identifier: AuthIdentifier;\n password?: string;\n profile?: Record<string, unknown>;\n redirectTo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SignOutInput {\n allDevices?: boolean;\n}\n\nexport interface PasswordResetInput {\n identifier: AuthIdentifier;\n redirectTo?: string;\n}\n\nexport interface VerifyOtpInput {\n identifier: AuthIdentifier;\n token: string;\n redirectTo?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport const AUTH_OAUTH_ERROR_STAGES = [\n 'start',\n 'transport',\n 'callback',\n 'exchange',\n 'session',\n 'profile',\n] as const;\nexport type AuthOAuthErrorStage = (typeof AUTH_OAUTH_ERROR_STAGES)[number];\n\nexport const AUTH_OAUTH_ERROR_CODES = [\n 'oauth_unavailable',\n 'provider_disabled',\n 'provider_misconfigured',\n 'invalid_redirect_uri',\n 'authorization_failed',\n 'authorization_attempt_not_found',\n 'invalid_callback',\n 'state_mismatch',\n 'pkce_mismatch',\n 'callback_already_completed',\n 'code_exchange_failed',\n 'network_error',\n 'session_persistence_failed',\n 'profile_creation_failed',\n 'provider_error',\n] as const;\nexport type AuthOAuthErrorCode = (typeof AUTH_OAUTH_ERROR_CODES)[number];\n\nexport interface AuthOAuthError extends AuthAdapterError {\n code: AuthOAuthErrorCode;\n stage: AuthOAuthErrorStage;\n provider?: AuthOAuthProviderId;\n recoverable: boolean;\n}\n\nexport const AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS = [\n 'user_cancelled',\n 'browser_dismissed',\n] as const;\nexport type AuthOAuthTransportCancellationReason =\n (typeof AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS)[number];\n\nexport const AUTH_OAUTH_CANCELLATION_REASONS = [\n ...AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS,\n 'provider_denied',\n] as const;\nexport type AuthOAuthCancellationReason = (typeof AUTH_OAUTH_CANCELLATION_REASONS)[number];\n\nexport const AUTH_OAUTH_TRANSPORT_ERROR_CODES = [\n 'browser_unavailable',\n 'transport_failed',\n] as const;\nexport type AuthOAuthTransportErrorCode = (typeof AUTH_OAUTH_TRANSPORT_ERROR_CODES)[number];\n\nexport interface AuthOAuthTransportError {\n code: AuthOAuthTransportErrorCode;\n message: string;\n cause?: unknown;\n}\n\nexport interface StartOAuthAuthorizationInput {\n provider: AuthOAuthProviderId;\n redirectUri: string;\n scopes?: readonly string[];\n queryParams?: Readonly<Record<string, string>>;\n}\n\nexport interface AuthOAuthAuthorizationRequest {\n attemptId: string;\n provider: AuthOAuthProviderId;\n authorizationUrl: string;\n redirectUri: string;\n}\n\nexport type AuthOAuthStartResult =\n | {\n ok: true;\n data: AuthOAuthAuthorizationRequest;\n }\n | {\n ok: false;\n error: AuthOAuthError;\n };\n\nexport type AuthOAuthAuthorizationResponse =\n | {\n type: 'callback';\n url: string;\n }\n | {\n type: 'cancelled';\n reason: AuthOAuthTransportCancellationReason;\n }\n | {\n type: 'error';\n error: AuthOAuthTransportError;\n };\n\nexport interface CompleteOAuthAuthorizationInput {\n attemptId: string;\n response: AuthOAuthAuthorizationResponse;\n}\n\nexport type AuthOAuthCompletionResult =\n | {\n ok: true;\n status: 'authenticated';\n provider: AuthOAuthProviderId;\n session: AuthSession;\n }\n | {\n ok: false;\n status: 'cancelled';\n provider: AuthOAuthProviderId;\n reason: AuthOAuthCancellationReason;\n }\n | {\n ok: false;\n status: 'error';\n error: AuthOAuthError;\n };\n\nexport interface AuthOAuthCapabilities {\n /** Enabled providers for which start and callback completion are operational. */\n providers: readonly [AuthOAuthProviderId, ...AuthOAuthProviderId[]];\n}\n\nexport interface AuthOAuthAdapter {\n readonly capabilities: AuthOAuthCapabilities;\n\n startAuthorization(input: StartOAuthAuthorizationInput): Promise<AuthOAuthStartResult>;\n completeAuthorization(input: CompleteOAuthAuthorizationInput): Promise<AuthOAuthCompletionResult>;\n}\n\nexport interface AuthAdapterCapabilities {\n signInIdentifiers: AuthIdentifierKind[];\n supportsSignUp: boolean;\n supportsPasswordReset: boolean;\n supportsOtp: boolean;\n supportsSessionRefresh: boolean;\n}\n\nexport interface AuthAdapter {\n readonly capabilities?: AuthAdapterCapabilities;\n /**\n * Presence is the canonical OAuth capability signal. When present, both authorization start and\n * callback completion are mandatory and operational for every advertised provider.\n */\n readonly oauth?: AuthOAuthAdapter;\n\n signIn(input: SignInInput): Promise<AuthResult<AuthSession>>;\n signUp(input: SignUpInput): Promise<AuthResult<AuthSession | AuthUser>>;\n signOut(input?: SignOutInput): Promise<AuthResult>;\n\n getSession(): Promise<AuthResult<AuthSession | null>>;\n refreshSession?(): Promise<AuthResult<AuthSession | null>>;\n\n requestPasswordReset?(input: PasswordResetInput): Promise<AuthResult>;\n verifyOtp?(input: VerifyOtpInput): Promise<AuthResult<AuthSession>>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ankhorage/contracts",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "main": "./dist/index.js",
5
5
  "ankh": {
6
6
  "category": "contracts",
@@ -1,12 +1,58 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
1
5
  import { describe, expect, it } from 'bun:test';
2
6
 
3
7
  import {
8
+ AUTH_OAUTH_CANCELLATION_REASONS,
9
+ AUTH_OAUTH_ERROR_CODES,
4
10
  AUTH_OAUTH_PROVIDER_IDS,
5
11
  type AuthAdapter,
6
12
  type AuthOAuthConfig,
13
+ type AuthSession,
7
14
  type AuthSpec,
8
15
  } from './index';
9
16
 
17
+ const session: AuthSession = {
18
+ accessToken: 'access-token',
19
+ refreshToken: 'refresh-token',
20
+ user: {
21
+ id: 'user-1',
22
+ email: 'person@example.com',
23
+ },
24
+ };
25
+
26
+ function createBaseAdapter(): Omit<AuthAdapter, 'oauth'> {
27
+ return {
28
+ capabilities: {
29
+ signInIdentifiers: ['email'],
30
+ supportsSignUp: true,
31
+ supportsPasswordReset: true,
32
+ supportsOtp: true,
33
+ supportsSessionRefresh: true,
34
+ },
35
+ signIn() {
36
+ return Promise.resolve({
37
+ ok: false,
38
+ error: { code: 'unsupported', message: 'Password sign-in is not implemented.' },
39
+ });
40
+ },
41
+ signUp() {
42
+ return Promise.resolve({
43
+ ok: false,
44
+ error: { code: 'unsupported', message: 'Sign-up is not implemented.' },
45
+ });
46
+ },
47
+ signOut() {
48
+ return Promise.resolve({ ok: true });
49
+ },
50
+ getSession() {
51
+ return Promise.resolve({ ok: true, data: null });
52
+ },
53
+ };
54
+ }
55
+
10
56
  describe('OAuth auth contracts', () => {
11
57
  it('accepts provider-neutral OAuth provider config on auth specs', () => {
12
58
  const oauth: AuthOAuthConfig = {
@@ -27,7 +73,6 @@ describe('OAuth auth contracts', () => {
27
73
  id: 'custom-sso',
28
74
  label: 'Custom SSO',
29
75
  enabled: false,
30
- redirectTo: '/auth/custom/callback',
31
76
  queryParams: {
32
77
  prompt: 'select_account',
33
78
  },
@@ -38,7 +83,6 @@ describe('OAuth auth contracts', () => {
38
83
  const auth: AuthSpec = {
39
84
  scope: 'global',
40
85
  provider: 'supabase',
41
- authorization: { kind: 'RBAC', engine: 'native' },
42
86
  oauth,
43
87
  };
44
88
 
@@ -48,56 +92,157 @@ describe('OAuth auth contracts', () => {
48
92
  expect(auth.oauth?.providers[1]?.enabled).toBe(false);
49
93
  });
50
94
 
51
- it('accepts optional OAuth adapter capabilities and redirect flow methods', async () => {
95
+ it('advertises OAuth only through one complete start and completion capability', async () => {
52
96
  const adapter: AuthAdapter = {
53
- capabilities: {
54
- signInIdentifiers: ['email'],
55
- supportsSignUp: true,
56
- supportsPasswordReset: true,
57
- supportsOtp: true,
58
- supportsSessionRefresh: true,
59
- supportsOAuth: true,
60
- oauthProviders: ['google', 'custom-sso'],
61
- },
62
- signIn() {
63
- return Promise.resolve({
64
- ok: false,
65
- error: { code: 'unsupported', message: 'Password sign-in is not implemented.' },
66
- });
67
- },
68
- signUp() {
69
- return Promise.resolve({
70
- ok: false,
71
- error: { code: 'unsupported', message: 'Sign-up is not implemented.' },
72
- });
73
- },
74
- signOut() {
75
- return Promise.resolve({ ok: true });
97
+ ...createBaseAdapter(),
98
+ oauth: {
99
+ capabilities: {
100
+ providers: ['google', 'custom-sso'],
101
+ },
102
+ startAuthorization(input) {
103
+ return Promise.resolve({
104
+ ok: true,
105
+ data: {
106
+ attemptId: 'oauth-attempt-1',
107
+ provider: input.provider,
108
+ authorizationUrl: `https://auth.example.com/oauth/${input.provider}`,
109
+ redirectUri: input.redirectUri,
110
+ },
111
+ });
112
+ },
113
+ completeAuthorization(input) {
114
+ if (input.response.type === 'cancelled') {
115
+ return Promise.resolve({
116
+ ok: false,
117
+ status: 'cancelled',
118
+ provider: 'google',
119
+ reason: input.response.reason,
120
+ });
121
+ }
122
+
123
+ if (input.response.type === 'error') {
124
+ return Promise.resolve({
125
+ ok: false,
126
+ status: 'error',
127
+ error: {
128
+ code: 'authorization_failed',
129
+ message: input.response.error.message,
130
+ stage: 'transport',
131
+ provider: 'google',
132
+ recoverable: true,
133
+ },
134
+ });
135
+ }
136
+
137
+ return Promise.resolve({
138
+ ok: true,
139
+ status: 'authenticated',
140
+ provider: 'google',
141
+ session,
142
+ });
143
+ },
76
144
  },
77
- getSession() {
78
- return Promise.resolve({ ok: true, data: null });
145
+ };
146
+
147
+ const started = await adapter.oauth?.startAuthorization({
148
+ provider: 'google',
149
+ redirectUri: 'ankh-app://auth/callback',
150
+ scopes: ['openid', 'email', 'profile'],
151
+ queryParams: { prompt: 'select_account' },
152
+ });
153
+
154
+ expect(adapter.oauth?.capabilities.providers).toEqual(['google', 'custom-sso']);
155
+ expect(started?.ok).toBe(true);
156
+ expect(started?.ok === true ? started.data.attemptId : undefined).toBe('oauth-attempt-1');
157
+ expect(started?.ok === true ? started.data.redirectUri : undefined).toBe(
158
+ 'ankh-app://auth/callback',
159
+ );
160
+
161
+ const completed = await adapter.oauth?.completeAuthorization({
162
+ attemptId: 'oauth-attempt-1',
163
+ response: {
164
+ type: 'callback',
165
+ url: 'ankh-app://auth/callback?code=opaque-code&state=opaque-state',
79
166
  },
80
- signInWithOAuth(input) {
81
- return Promise.resolve({
82
- ok: true,
83
- data: {
84
- provider: input.provider,
85
- url: `https://auth.example.com/oauth/${input.provider}`,
86
- },
87
- });
167
+ });
168
+
169
+ expect(completed?.status).toBe('authenticated');
170
+ expect(completed?.ok === true ? completed.session : undefined).toEqual(session);
171
+ });
172
+
173
+ it('models user cancellation separately from OAuth failures', async () => {
174
+ const adapter: AuthAdapter = {
175
+ ...createBaseAdapter(),
176
+ oauth: {
177
+ capabilities: { providers: ['google'] },
178
+ startAuthorization(input) {
179
+ return Promise.resolve({
180
+ ok: true,
181
+ data: {
182
+ attemptId: 'oauth-attempt-2',
183
+ provider: input.provider,
184
+ authorizationUrl: 'https://auth.example.com/oauth/google',
185
+ redirectUri: input.redirectUri,
186
+ },
187
+ });
188
+ },
189
+ completeAuthorization(input) {
190
+ if (input.response.type === 'cancelled') {
191
+ return Promise.resolve({
192
+ ok: false,
193
+ status: 'cancelled',
194
+ provider: 'google',
195
+ reason: input.response.reason,
196
+ });
197
+ }
198
+
199
+ return Promise.resolve({
200
+ ok: false,
201
+ status: 'error',
202
+ error: {
203
+ code: 'invalid_callback',
204
+ message: 'The OAuth callback is invalid.',
205
+ stage: 'callback',
206
+ provider: 'google',
207
+ recoverable: true,
208
+ },
209
+ });
210
+ },
88
211
  },
89
212
  };
90
213
 
91
- const result = await adapter.signInWithOAuth?.({
214
+ const cancelled = await adapter.oauth?.completeAuthorization({
215
+ attemptId: 'oauth-attempt-2',
216
+ response: { type: 'cancelled', reason: 'browser_dismissed' },
217
+ });
218
+
219
+ expect(AUTH_OAUTH_CANCELLATION_REASONS).toContain('provider_denied');
220
+ expect(AUTH_OAUTH_ERROR_CODES).toContain('pkce_mismatch');
221
+ expect(cancelled).toEqual({
222
+ ok: false,
223
+ status: 'cancelled',
92
224
  provider: 'google',
93
- redirectTo: '/auth/callback',
94
- scopes: ['openid', 'email', 'profile'],
225
+ reason: 'browser_dismissed',
95
226
  });
227
+ });
228
+
229
+ it('removes the superseded URL-only OAuth adapter surface', () => {
230
+ const source = readFileSync(
231
+ path.join(path.dirname(fileURLToPath(import.meta.url)), 'auth.ts'),
232
+ 'utf8',
233
+ );
234
+ const removedSymbols = [
235
+ 'SignInWith' + 'OAuthInput',
236
+ 'AuthOAuth' + 'Redirect',
237
+ 'CompleteOAuth' + 'SignInInput',
238
+ 'signInWith' + 'OAuth',
239
+ 'completeOAuth' + 'SignIn',
240
+ 'supports' + 'OAuth',
241
+ 'oauth' + 'Providers',
242
+ ];
96
243
 
97
- expect(adapter.capabilities?.supportsOAuth).toBe(true);
98
- expect(adapter.capabilities?.oauthProviders).toEqual(['google', 'custom-sso']);
99
- expect(result?.ok).toBe(true);
100
- expect(result?.ok === true ? result.data?.provider : undefined).toBe('google');
101
- expect(result?.ok === true ? result.data?.url : undefined).toContain('/oauth/google');
244
+ for (const symbol of removedSymbols) {
245
+ expect(source).not.toContain(symbol);
246
+ }
102
247
  });
103
248
  });
package/src/auth.ts CHANGED
@@ -80,7 +80,6 @@ export interface AuthOAuthProviderConfig {
80
80
  label?: string;
81
81
  enabled?: boolean;
82
82
  scopes?: string[];
83
- redirectTo?: string;
84
83
  queryParams?: Record<string, string>;
85
84
  icon?: IconSpec;
86
85
  /** Logical server-side secret reference; raw credentials must never be stored here. */
@@ -172,22 +171,139 @@ export interface VerifyOtpInput {
172
171
  metadata?: Record<string, unknown>;
173
172
  }
174
173
 
175
- export interface SignInWithOAuthInput {
174
+ export const AUTH_OAUTH_ERROR_STAGES = [
175
+ 'start',
176
+ 'transport',
177
+ 'callback',
178
+ 'exchange',
179
+ 'session',
180
+ 'profile',
181
+ ] as const;
182
+ export type AuthOAuthErrorStage = (typeof AUTH_OAUTH_ERROR_STAGES)[number];
183
+
184
+ export const AUTH_OAUTH_ERROR_CODES = [
185
+ 'oauth_unavailable',
186
+ 'provider_disabled',
187
+ 'provider_misconfigured',
188
+ 'invalid_redirect_uri',
189
+ 'authorization_failed',
190
+ 'authorization_attempt_not_found',
191
+ 'invalid_callback',
192
+ 'state_mismatch',
193
+ 'pkce_mismatch',
194
+ 'callback_already_completed',
195
+ 'code_exchange_failed',
196
+ 'network_error',
197
+ 'session_persistence_failed',
198
+ 'profile_creation_failed',
199
+ 'provider_error',
200
+ ] as const;
201
+ export type AuthOAuthErrorCode = (typeof AUTH_OAUTH_ERROR_CODES)[number];
202
+
203
+ export interface AuthOAuthError extends AuthAdapterError {
204
+ code: AuthOAuthErrorCode;
205
+ stage: AuthOAuthErrorStage;
206
+ provider?: AuthOAuthProviderId;
207
+ recoverable: boolean;
208
+ }
209
+
210
+ export const AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS = [
211
+ 'user_cancelled',
212
+ 'browser_dismissed',
213
+ ] as const;
214
+ export type AuthOAuthTransportCancellationReason =
215
+ (typeof AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS)[number];
216
+
217
+ export const AUTH_OAUTH_CANCELLATION_REASONS = [
218
+ ...AUTH_OAUTH_TRANSPORT_CANCELLATION_REASONS,
219
+ 'provider_denied',
220
+ ] as const;
221
+ export type AuthOAuthCancellationReason = (typeof AUTH_OAUTH_CANCELLATION_REASONS)[number];
222
+
223
+ export const AUTH_OAUTH_TRANSPORT_ERROR_CODES = [
224
+ 'browser_unavailable',
225
+ 'transport_failed',
226
+ ] as const;
227
+ export type AuthOAuthTransportErrorCode = (typeof AUTH_OAUTH_TRANSPORT_ERROR_CODES)[number];
228
+
229
+ export interface AuthOAuthTransportError {
230
+ code: AuthOAuthTransportErrorCode;
231
+ message: string;
232
+ cause?: unknown;
233
+ }
234
+
235
+ export interface StartOAuthAuthorizationInput {
176
236
  provider: AuthOAuthProviderId;
177
- redirectTo?: string;
178
- scopes?: string[];
179
- queryParams?: Record<string, string>;
180
- metadata?: Record<string, unknown>;
237
+ redirectUri: string;
238
+ scopes?: readonly string[];
239
+ queryParams?: Readonly<Record<string, string>>;
181
240
  }
182
241
 
183
- export interface AuthOAuthRedirect {
242
+ export interface AuthOAuthAuthorizationRequest {
243
+ attemptId: string;
184
244
  provider: AuthOAuthProviderId;
185
- url: string;
245
+ authorizationUrl: string;
246
+ redirectUri: string;
186
247
  }
187
248
 
188
- export interface CompleteOAuthSignInInput {
189
- url: string;
190
- redirectTo?: string;
249
+ export type AuthOAuthStartResult =
250
+ | {
251
+ ok: true;
252
+ data: AuthOAuthAuthorizationRequest;
253
+ }
254
+ | {
255
+ ok: false;
256
+ error: AuthOAuthError;
257
+ };
258
+
259
+ export type AuthOAuthAuthorizationResponse =
260
+ | {
261
+ type: 'callback';
262
+ url: string;
263
+ }
264
+ | {
265
+ type: 'cancelled';
266
+ reason: AuthOAuthTransportCancellationReason;
267
+ }
268
+ | {
269
+ type: 'error';
270
+ error: AuthOAuthTransportError;
271
+ };
272
+
273
+ export interface CompleteOAuthAuthorizationInput {
274
+ attemptId: string;
275
+ response: AuthOAuthAuthorizationResponse;
276
+ }
277
+
278
+ export type AuthOAuthCompletionResult =
279
+ | {
280
+ ok: true;
281
+ status: 'authenticated';
282
+ provider: AuthOAuthProviderId;
283
+ session: AuthSession;
284
+ }
285
+ | {
286
+ ok: false;
287
+ status: 'cancelled';
288
+ provider: AuthOAuthProviderId;
289
+ reason: AuthOAuthCancellationReason;
290
+ }
291
+ | {
292
+ ok: false;
293
+ status: 'error';
294
+ error: AuthOAuthError;
295
+ };
296
+
297
+ export interface AuthOAuthCapabilities {
298
+ /** Enabled providers for which start and callback completion are operational. */
299
+ providers: readonly [AuthOAuthProviderId, ...AuthOAuthProviderId[]];
300
+ }
301
+
302
+ export interface AuthOAuthAdapter {
303
+ readonly capabilities: AuthOAuthCapabilities;
304
+
305
+ startAuthorization(input: StartOAuthAuthorizationInput): Promise<AuthOAuthStartResult>;
306
+ completeAuthorization(input: CompleteOAuthAuthorizationInput): Promise<AuthOAuthCompletionResult>;
191
307
  }
192
308
 
193
309
  export interface AuthAdapterCapabilities {
@@ -196,12 +312,15 @@ export interface AuthAdapterCapabilities {
196
312
  supportsPasswordReset: boolean;
197
313
  supportsOtp: boolean;
198
314
  supportsSessionRefresh: boolean;
199
- supportsOAuth?: boolean;
200
- oauthProviders?: AuthOAuthProviderId[];
201
315
  }
202
316
 
203
317
  export interface AuthAdapter {
204
318
  readonly capabilities?: AuthAdapterCapabilities;
319
+ /**
320
+ * Presence is the canonical OAuth capability signal. When present, both authorization start and
321
+ * callback completion are mandatory and operational for every advertised provider.
322
+ */
323
+ readonly oauth?: AuthOAuthAdapter;
205
324
 
206
325
  signIn(input: SignInInput): Promise<AuthResult<AuthSession>>;
207
326
  signUp(input: SignUpInput): Promise<AuthResult<AuthSession | AuthUser>>;
@@ -212,7 +331,4 @@ export interface AuthAdapter {
212
331
 
213
332
  requestPasswordReset?(input: PasswordResetInput): Promise<AuthResult>;
214
333
  verifyOtp?(input: VerifyOtpInput): Promise<AuthResult<AuthSession>>;
215
-
216
- signInWithOAuth?(input: SignInWithOAuthInput): Promise<AuthResult<AuthOAuthRedirect>>;
217
- completeOAuthSignIn?(input: CompleteOAuthSignInInput): Promise<AuthResult<AuthSession>>;
218
334
  }