@aooth/idp 0.2.1 → 0.2.2
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/index.cjs +14 -25
- package/dist/index.d.cts +19 -41
- package/dist/index.d.mts +19 -41
- package/dist/index.mjs +14 -25
- package/package.json +4 -6
package/dist/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@ let node_crypto = require("node:crypto");
|
|
|
3
3
|
let _aooth_auth = require("@aooth/auth");
|
|
4
4
|
let jose = require("jose");
|
|
5
5
|
let _aooth_user = require("@aooth/user");
|
|
6
|
-
|
|
6
|
+
// src/errors.ts
|
|
7
7
|
const defaultMessages = {
|
|
8
8
|
UNKNOWN_PROVIDER: "Unknown identity provider",
|
|
9
9
|
INVALID_CONFIG: "Invalid OAuth provider configuration",
|
|
@@ -25,8 +25,7 @@ var OAuthError = class extends Error {
|
|
|
25
25
|
this.details = details;
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
|
-
|
|
29
|
-
//#region src/types.ts
|
|
28
|
+
// src/types.ts
|
|
30
29
|
/** Structural check used by the registry to feature-detect `applyDefaults`. */
|
|
31
30
|
function isConfigurableProvider(p) {
|
|
32
31
|
return typeof p.applyDefaults === "function";
|
|
@@ -44,8 +43,7 @@ function resolveFederatedPolicy(policy = {}) {
|
|
|
44
43
|
trustEmailVerifiedFrom: policy.trustEmailVerifiedFrom ?? []
|
|
45
44
|
};
|
|
46
45
|
}
|
|
47
|
-
|
|
48
|
-
//#region src/pkce.ts
|
|
46
|
+
// src/pkce.ts
|
|
49
47
|
/**
|
|
50
48
|
* PKCE / CSRF primitives (RFC 7636 + OIDC nonce). All values are URL-safe
|
|
51
49
|
* base64url with no padding, so they ride in query params and cookies without
|
|
@@ -107,8 +105,7 @@ function deriveSeededPkce(secret, seed) {
|
|
|
107
105
|
method: "S256"
|
|
108
106
|
};
|
|
109
107
|
}
|
|
110
|
-
|
|
111
|
-
//#region src/state.ts
|
|
108
|
+
// src/state.ts
|
|
112
109
|
const DEFAULT_TTL_SEC = 600;
|
|
113
110
|
function toKey(secret) {
|
|
114
111
|
return typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
@@ -163,8 +160,7 @@ async function verifyState(token, secret, opts = {}) {
|
|
|
163
160
|
if (typeof payload.uid === "string") out.userId = payload.uid;
|
|
164
161
|
return out;
|
|
165
162
|
}
|
|
166
|
-
|
|
167
|
-
//#region src/providers/oauth2-shared.ts
|
|
163
|
+
// src/providers/oauth2-shared.ts
|
|
168
164
|
/** Resolve the effective `fetch`: an injected impl, else the global `fetch`. */
|
|
169
165
|
function resolveFetch(impl) {
|
|
170
166
|
return impl ?? globalThis.fetch;
|
|
@@ -213,8 +209,7 @@ function buildAuthorizeUrl(endpoint, args, opts = {}) {
|
|
|
213
209
|
for (const [k, v] of Object.entries(opts.extraParams ?? {})) url.searchParams.set(k, v);
|
|
214
210
|
return url.toString();
|
|
215
211
|
}
|
|
216
|
-
|
|
217
|
-
//#region src/providers/oidc.ts
|
|
212
|
+
// src/providers/oidc.ts
|
|
218
213
|
const DEFAULT_SCOPES$1 = [
|
|
219
214
|
"openid",
|
|
220
215
|
"email",
|
|
@@ -416,11 +411,11 @@ var OidcProvider = class {
|
|
|
416
411
|
* token's hash, the hash chosen by the id_token's `alg` (RS256 → SHA-256).
|
|
417
412
|
*/
|
|
418
413
|
function atHash(accessToken, alg) {
|
|
419
|
-
const
|
|
414
|
+
const sha = alg.endsWith("384") ? "sha384" : alg.endsWith("512") ? "sha512" : "sha256";
|
|
415
|
+
const digest = (0, node_crypto.createHash)(sha).update(accessToken).digest();
|
|
420
416
|
return digest.subarray(0, digest.length / 2).toString("base64url");
|
|
421
417
|
}
|
|
422
|
-
|
|
423
|
-
//#region src/providers/google.ts
|
|
418
|
+
// src/providers/google.ts
|
|
424
419
|
/** Google's stable OIDC issuer — endpoints + JWKS are discovered from it. */
|
|
425
420
|
const GOOGLE_ISSUER = "https://accounts.google.com";
|
|
426
421
|
/**
|
|
@@ -438,8 +433,7 @@ var GoogleProvider = class extends OidcProvider {
|
|
|
438
433
|
});
|
|
439
434
|
}
|
|
440
435
|
};
|
|
441
|
-
|
|
442
|
-
//#region src/providers/github.ts
|
|
436
|
+
// src/providers/github.ts
|
|
443
437
|
const GITHUB_AUTHORIZE = "https://github.com/login/oauth/authorize";
|
|
444
438
|
const GITHUB_TOKEN = "https://github.com/login/oauth/access_token";
|
|
445
439
|
const GITHUB_USER = "https://api.github.com/user";
|
|
@@ -576,8 +570,7 @@ var GithubProvider = class {
|
|
|
576
570
|
}, { label: `GitHub API (${url})` });
|
|
577
571
|
}
|
|
578
572
|
};
|
|
579
|
-
|
|
580
|
-
//#region src/providers/apple.ts
|
|
573
|
+
// src/providers/apple.ts
|
|
581
574
|
/** Apple's stable OIDC issuer — endpoints + JWKS are discovered from it. */
|
|
582
575
|
const APPLE_ISSUER = "https://appleid.apple.com";
|
|
583
576
|
/** Apple ID tokens are always ES256. */
|
|
@@ -681,8 +674,7 @@ var AppleProvider = class extends OidcProvider {
|
|
|
681
674
|
return profile;
|
|
682
675
|
}
|
|
683
676
|
};
|
|
684
|
-
|
|
685
|
-
//#region src/providers/fake.ts
|
|
677
|
+
// src/providers/fake.ts
|
|
686
678
|
/**
|
|
687
679
|
* Deterministic, network-free {@link IdentityProvider} for unit tests and the
|
|
688
680
|
* `DEMO_MODE=test` fake-IdP e2e route (RFC §9). `exchange` resolves a `code`
|
|
@@ -719,8 +711,7 @@ var FakeIdentityProvider = class {
|
|
|
719
711
|
});
|
|
720
712
|
}
|
|
721
713
|
};
|
|
722
|
-
|
|
723
|
-
//#region src/registry.ts
|
|
714
|
+
// src/registry.ts
|
|
724
715
|
const DEFAULT_CALLBACK_TEMPLATE = "/auth/oauth/:provider/callback";
|
|
725
716
|
/**
|
|
726
717
|
* Holds the configured {@link IdentityProvider}s + {@link FederatedPolicy} +
|
|
@@ -802,8 +793,7 @@ var OAuthProviderRegistry = class {
|
|
|
802
793
|
return deriveSeededPkce(this.stateSecret, seed);
|
|
803
794
|
}
|
|
804
795
|
};
|
|
805
|
-
|
|
806
|
-
//#region src/federated-login-service.ts
|
|
796
|
+
// src/federated-login-service.ts
|
|
807
797
|
/**
|
|
808
798
|
* The core federated-login logic (RFC §3.5): map a verified provider profile to
|
|
809
799
|
* an aooth user id. Pure orchestration over `UserService` + `FederatedIdentityStore`
|
|
@@ -940,7 +930,6 @@ var FederatedLoginService = class {
|
|
|
940
930
|
return this.federated.touchLogin(profile.provider, profile.subject, (0, _aooth_user.pickDefinedProfile)(profile));
|
|
941
931
|
}
|
|
942
932
|
};
|
|
943
|
-
//#endregion
|
|
944
933
|
exports.AppleProvider = AppleProvider;
|
|
945
934
|
exports.FakeIdentityProvider = FakeIdentityProvider;
|
|
946
935
|
exports.FederatedLoginService = FederatedLoginService;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Clock } from "@aooth/auth";
|
|
2
2
|
import { FederatedIdentity, FederatedIdentityStore, FederatedProfileSnapshot, UserService } from "@aooth/user";
|
|
3
3
|
import { JWTPayload, JWTVerifyGetKey } from "jose";
|
|
4
|
-
//#region src/errors.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Federated-login failure taxonomy (RFC IDP.md §8). Mirrors `AuthError` /
|
|
7
6
|
* `UserAuthError` — a typed `Error` with a stable `type` code, an optional
|
|
@@ -30,14 +29,12 @@ type OAuthErrorType =
|
|
|
30
29
|
"ID_TOKEN_INVALID" |
|
|
31
30
|
/** Policy needed a verified email but the provider returned none. */
|
|
32
31
|
"EMAIL_UNAVAILABLE";
|
|
33
|
-
declare class OAuthError extends Error {
|
|
32
|
+
export declare class OAuthError extends Error {
|
|
34
33
|
readonly type: OAuthErrorType;
|
|
35
34
|
readonly details?: Record<string, unknown> | undefined;
|
|
36
35
|
readonly name = "OAuthError";
|
|
37
36
|
constructor(type: OAuthErrorType, message?: string, details?: Record<string, unknown> | undefined);
|
|
38
37
|
}
|
|
39
|
-
//#endregion
|
|
40
|
-
//#region src/types.d.ts
|
|
41
38
|
/**
|
|
42
39
|
* A provider profile normalized to a single shape across Google / OIDC / etc.
|
|
43
40
|
* Structural superset of `@aooth/user`'s {@link FederatedProfileSnapshot} (the
|
|
@@ -139,7 +136,7 @@ interface ConfigurableProvider extends IdentityProvider {
|
|
|
139
136
|
applyDefaults(shared: SharedProviderConfig): void;
|
|
140
137
|
}
|
|
141
138
|
/** Structural check used by the registry to feature-detect `applyDefaults`. */
|
|
142
|
-
declare function isConfigurableProvider(p: IdentityProvider): p is ConfigurableProvider;
|
|
139
|
+
export declare function isConfigurableProvider(p: IdentityProvider): p is ConfigurableProvider;
|
|
143
140
|
/**
|
|
144
141
|
* How a federated login that matches an existing local account **by email**
|
|
145
142
|
* is handled (RFC §4 — the account-takeover-sensitive knob).
|
|
@@ -166,9 +163,9 @@ interface FederatedPolicy {
|
|
|
166
163
|
}
|
|
167
164
|
type ResolvedFederatedPolicy = Required<FederatedPolicy>;
|
|
168
165
|
/** Default username strategy: the verified email, else the stable `provider:subject`. */
|
|
169
|
-
declare function defaultUsernameStrategy(p: NormalizedProfile): string;
|
|
166
|
+
export declare function defaultUsernameStrategy(p: NormalizedProfile): string;
|
|
170
167
|
/** Apply RFC §4 safe defaults over a partial policy. */
|
|
171
|
-
declare function resolveFederatedPolicy(policy?: FederatedPolicy): ResolvedFederatedPolicy;
|
|
168
|
+
export declare function resolveFederatedPolicy(policy?: FederatedPolicy): ResolvedFederatedPolicy;
|
|
172
169
|
/**
|
|
173
170
|
* The outcome of {@link FederatedLoginService.resolveUser} (decision #1). A
|
|
174
171
|
* discriminated union — richer than the RFC's `{ userId, isNew }` sketch — so
|
|
@@ -205,8 +202,6 @@ type ResolveOutcome =
|
|
|
205
202
|
kind: "denied";
|
|
206
203
|
reason: "signup-disabled" | "email-unavailable";
|
|
207
204
|
};
|
|
208
|
-
//#endregion
|
|
209
|
-
//#region src/pkce.d.ts
|
|
210
205
|
interface PkcePair {
|
|
211
206
|
/** The high-entropy secret kept server-side (cookie / wf state). */
|
|
212
207
|
verifier: string;
|
|
@@ -229,13 +224,13 @@ interface SeededPkce {
|
|
|
229
224
|
* Mint a fresh PKCE pair. The 32-byte verifier base64url-encodes to 43 chars,
|
|
230
225
|
* comfortably inside RFC 7636's 43–128 range.
|
|
231
226
|
*/
|
|
232
|
-
declare function createPkcePair(): PkcePair;
|
|
227
|
+
export declare function createPkcePair(): PkcePair;
|
|
233
228
|
/** Recompute the S256 challenge for a known verifier (verification side). */
|
|
234
|
-
declare function pkceChallengeFor(verifier: string): string;
|
|
229
|
+
export declare function pkceChallengeFor(verifier: string): string;
|
|
235
230
|
/** OIDC `nonce` — minted at `/start`, bound into state, asserted in `exchange()`. */
|
|
236
|
-
declare function generateNonce(bytes?: number): string;
|
|
231
|
+
export declare function generateNonce(bytes?: number): string;
|
|
237
232
|
/** Random component bound into the signed `state` (anti-CSRF / anti-replay). */
|
|
238
|
-
declare function generateRandomState(bytes?: number): string;
|
|
233
|
+
export declare function generateRandomState(bytes?: number): string;
|
|
239
234
|
/**
|
|
240
235
|
* STATELESS PKCE: deterministically DERIVE the code verifier + OIDC nonce from
|
|
241
236
|
* a non-secret `seed` and the server's HMAC `secret`, instead of minting them
|
|
@@ -255,9 +250,7 @@ declare function generateRandomState(bytes?: number): string;
|
|
|
255
250
|
* Same output range as {@link createPkcePair}: a 32-byte HMAC-SHA256 digest →
|
|
256
251
|
* a 43-char base64url verifier, inside RFC 7636's 43–128.
|
|
257
252
|
*/
|
|
258
|
-
declare function deriveSeededPkce(secret: string | Uint8Array, seed: string): SeededPkce;
|
|
259
|
-
//#endregion
|
|
260
|
-
//#region src/state.d.ts
|
|
253
|
+
export declare function deriveSeededPkce(secret: string | Uint8Array, seed: string): SeededPkce;
|
|
261
254
|
/**
|
|
262
255
|
* The CSRF/replay binding carried across the OAuth bounce (RFC §7). Signed into
|
|
263
256
|
* a compact HS256 JWT by {@link signState} so it is tamper-evident in the URL
|
|
@@ -293,15 +286,13 @@ interface VerifyStateOptions {
|
|
|
293
286
|
* Sign the binding into a compact HS256 JWT. Field names are abbreviated to
|
|
294
287
|
* keep the URL `state` short; {@link verifyState} maps them back.
|
|
295
288
|
*/
|
|
296
|
-
declare function signState(payload: OAuthStatePayload, secret: string | Uint8Array, opts?: SignStateOptions): Promise<string>;
|
|
289
|
+
export declare function signState(payload: OAuthStatePayload, secret: string | Uint8Array, opts?: SignStateOptions): Promise<string>;
|
|
297
290
|
/**
|
|
298
291
|
* Verify + decode the signed state. Pins `HS256` (rejects `alg:none` / key
|
|
299
292
|
* confusion). Throws {@link OAuthError} `STATE_EXPIRED` past TTL,
|
|
300
293
|
* `STATE_INVALID` on any other signature/shape failure.
|
|
301
294
|
*/
|
|
302
|
-
declare function verifyState(token: string, secret: string | Uint8Array, opts?: VerifyStateOptions): Promise<OAuthStatePayload>;
|
|
303
|
-
//#endregion
|
|
304
|
-
//#region src/providers/oidc.d.ts
|
|
295
|
+
export declare function verifyState(token: string, secret: string | Uint8Array, opts?: VerifyStateOptions): Promise<OAuthStatePayload>;
|
|
305
296
|
/** The four endpoints the OIDC client needs — discovered or supplied explicitly. */
|
|
306
297
|
interface OidcDiscoveryDocument {
|
|
307
298
|
issuer: string;
|
|
@@ -365,7 +356,7 @@ interface OidcProviderOptions {
|
|
|
365
356
|
*
|
|
366
357
|
* `GoogleProvider` is a thin subclass pinning the issuer + algs.
|
|
367
358
|
*/
|
|
368
|
-
declare class OidcProvider implements ConfigurableProvider {
|
|
359
|
+
export declare class OidcProvider implements ConfigurableProvider {
|
|
369
360
|
readonly id: string;
|
|
370
361
|
protected readonly issuer: string;
|
|
371
362
|
protected readonly clientId: string;
|
|
@@ -413,8 +404,6 @@ declare class OidcProvider implements ConfigurableProvider {
|
|
|
413
404
|
private validateDiscovery;
|
|
414
405
|
private getJwks;
|
|
415
406
|
}
|
|
416
|
-
//#endregion
|
|
417
|
-
//#region src/providers/google.d.ts
|
|
418
407
|
/** Google options = OIDC options minus the pinned `id`/`issuer`. */
|
|
419
408
|
type GoogleProviderOptions = Omit<OidcProviderOptions, "id" | "issuer">;
|
|
420
409
|
/**
|
|
@@ -422,11 +411,9 @@ type GoogleProviderOptions = Omit<OidcProviderOptions, "id" | "issuer">;
|
|
|
422
411
|
* (Google's only ID-token alg). Everything else — discovery, JWKS rotation,
|
|
423
412
|
* the full §7 validation — is inherited from {@link OidcProvider}.
|
|
424
413
|
*/
|
|
425
|
-
declare class GoogleProvider extends OidcProvider {
|
|
414
|
+
export declare class GoogleProvider extends OidcProvider {
|
|
426
415
|
constructor(opts: GoogleProviderOptions);
|
|
427
416
|
}
|
|
428
|
-
//#endregion
|
|
429
|
-
//#region src/providers/github.d.ts
|
|
430
417
|
interface GithubProviderOptions {
|
|
431
418
|
/** Provider id. Default `'github'`. */
|
|
432
419
|
id?: string;
|
|
@@ -457,7 +444,7 @@ interface GithubProviderOptions {
|
|
|
457
444
|
* Implements {@link ConfigurableProvider} so the registry can inject a shared
|
|
458
445
|
* `fetch` (deterministic tests) / `clock`; a constructor value always wins.
|
|
459
446
|
*/
|
|
460
|
-
declare class GithubProvider implements ConfigurableProvider {
|
|
447
|
+
export declare class GithubProvider implements ConfigurableProvider {
|
|
461
448
|
readonly id: string;
|
|
462
449
|
private readonly clientId;
|
|
463
450
|
private readonly clientSecret;
|
|
@@ -486,8 +473,6 @@ declare class GithubProvider implements ConfigurableProvider {
|
|
|
486
473
|
private fetchPrimaryEmail;
|
|
487
474
|
private apiGet;
|
|
488
475
|
}
|
|
489
|
-
//#endregion
|
|
490
|
-
//#region src/providers/apple.d.ts
|
|
491
476
|
interface AppleProviderOptions extends Omit<OidcProviderOptions, "id" | "issuer" | "clientSecret" | "idTokenSigningAlgs" | "scopes"> {
|
|
492
477
|
/** The Services ID — Sign in with Apple's OAuth `client_id` (and the id_token `aud`). */
|
|
493
478
|
clientId: string;
|
|
@@ -527,15 +512,13 @@ interface AppleProviderOptions extends Omit<OidcProviderOptions, "id" | "issuer"
|
|
|
527
512
|
* capture it, so `displayName` is undefined for Apple. Collect a display name
|
|
528
513
|
* post-signup if you need one.
|
|
529
514
|
*/
|
|
530
|
-
declare class AppleProvider extends OidcProvider {
|
|
515
|
+
export declare class AppleProvider extends OidcProvider {
|
|
531
516
|
constructor(opts: AppleProviderOptions);
|
|
532
517
|
/** `email`/`name` scope makes Apple POST the callback — declare `form_post`. */
|
|
533
518
|
protected extraAuthorizationParams(_args: AuthorizationUrlArgs): Record<string, string>;
|
|
534
519
|
/** Coerce Apple's STRING `email_verified` (the base sets only a real boolean). */
|
|
535
520
|
protected normalize(payload: JWTPayload): NormalizedProfile;
|
|
536
521
|
}
|
|
537
|
-
//#endregion
|
|
538
|
-
//#region src/providers/fake.d.ts
|
|
539
522
|
interface FakeIdentityProviderOptions {
|
|
540
523
|
/** Provider id. Default `'fake'`. */
|
|
541
524
|
id?: string;
|
|
@@ -553,7 +536,7 @@ interface FakeIdentityProviderOptions {
|
|
|
553
536
|
* It does NOT verify a nonce — it is the trusted test double; the real §7
|
|
554
537
|
* nonce/JWKS assertions are exercised against {@link OidcProvider} with `jose`.
|
|
555
538
|
*/
|
|
556
|
-
declare class FakeIdentityProvider implements IdentityProvider {
|
|
539
|
+
export declare class FakeIdentityProvider implements IdentityProvider {
|
|
557
540
|
readonly id: string;
|
|
558
541
|
private readonly authorizationEndpoint;
|
|
559
542
|
private readonly defaultProfile?;
|
|
@@ -564,8 +547,6 @@ declare class FakeIdentityProvider implements IdentityProvider {
|
|
|
564
547
|
authorizationUrl(args: AuthorizationUrlArgs): Promise<string>;
|
|
565
548
|
exchange(args: ExchangeArgs): Promise<NormalizedProfile>;
|
|
566
549
|
}
|
|
567
|
-
//#endregion
|
|
568
|
-
//#region src/registry.d.ts
|
|
569
550
|
interface OAuthProviderRegistryOptions {
|
|
570
551
|
/** Public origin — `redirect_uri` is built as `baseUrl` + the callback path (§3.7). */
|
|
571
552
|
baseUrl: string;
|
|
@@ -595,7 +576,7 @@ interface OAuthProviderRegistryOptions {
|
|
|
595
576
|
* each provider that implements `applyDefaults`, and builds the per-provider
|
|
596
577
|
* fixed redirect URIs.
|
|
597
578
|
*/
|
|
598
|
-
declare class OAuthProviderRegistry {
|
|
579
|
+
export declare class OAuthProviderRegistry {
|
|
599
580
|
readonly baseUrl: string;
|
|
600
581
|
readonly stateSecret: string;
|
|
601
582
|
readonly policy: ResolvedFederatedPolicy;
|
|
@@ -628,8 +609,6 @@ declare class OAuthProviderRegistry {
|
|
|
628
609
|
*/
|
|
629
610
|
deriveSeededPkce(seed: string): SeededPkce;
|
|
630
611
|
}
|
|
631
|
-
//#endregion
|
|
632
|
-
//#region src/federated-login-service.d.ts
|
|
633
612
|
interface FederatedLoginServiceDeps<T extends object = object> {
|
|
634
613
|
/** Concrete user orchestrator (RFC: idp depends on the concrete class). */
|
|
635
614
|
users: UserService<T>;
|
|
@@ -648,7 +627,7 @@ interface FederatedLoginServiceDeps<T extends object = object> {
|
|
|
648
627
|
* Generic over the user shape `T` so a consumer's `UserService<DemoUser>` plugs
|
|
649
628
|
* in directly; `resolveUser` only reads base `UserCredentials` fields.
|
|
650
629
|
*/
|
|
651
|
-
declare class FederatedLoginService<T extends object = object> {
|
|
630
|
+
export declare class FederatedLoginService<T extends object = object> {
|
|
652
631
|
private readonly users;
|
|
653
632
|
private readonly federated;
|
|
654
633
|
readonly policy: ResolvedFederatedPolicy;
|
|
@@ -698,5 +677,4 @@ declare class FederatedLoginService<T extends object = object> {
|
|
|
698
677
|
private newIdentity;
|
|
699
678
|
private touch;
|
|
700
679
|
}
|
|
701
|
-
|
|
702
|
-
export { AppleProvider, type AppleProviderOptions, type AuthorizationUrlArgs, type ConfigurableProvider, type EmailMatchPolicy, type ExchangeArgs, FakeIdentityProvider, type FakeIdentityProviderOptions, FederatedLoginService, type FederatedLoginServiceDeps, type FederatedPolicy, type FetchLike, type FetchResponseLike, GithubProvider, type GithubProviderOptions, GoogleProvider, type GoogleProviderOptions, type IdentityProvider, type NormalizedProfile, OAuthError, type OAuthErrorType, OAuthProviderRegistry, type OAuthProviderRegistryOptions, type OAuthStatePayload, type OidcDiscoveryDocument, OidcProvider, type OidcProviderOptions, type PkcePair, type ResolveOutcome, type ResolvedFederatedPolicy, type SeededPkce, type SharedProviderConfig, type SignStateOptions, type VerifyStateOptions, createPkcePair, defaultUsernameStrategy, deriveSeededPkce, generateNonce, generateRandomState, isConfigurableProvider, pkceChallengeFor, resolveFederatedPolicy, signState, verifyState };
|
|
680
|
+
export type { AppleProviderOptions, AuthorizationUrlArgs, ConfigurableProvider, EmailMatchPolicy, ExchangeArgs, FakeIdentityProviderOptions, FederatedLoginServiceDeps, FederatedPolicy, FetchLike, FetchResponseLike, GithubProviderOptions, GoogleProviderOptions, IdentityProvider, NormalizedProfile, OAuthErrorType, OAuthProviderRegistryOptions, OAuthStatePayload, OidcDiscoveryDocument, OidcProviderOptions, PkcePair, ResolveOutcome, ResolvedFederatedPolicy, SeededPkce, SharedProviderConfig, SignStateOptions, VerifyStateOptions };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Clock } from "@aooth/auth";
|
|
2
2
|
import { JWTPayload, JWTVerifyGetKey } from "jose";
|
|
3
3
|
import { FederatedIdentity, FederatedIdentityStore, FederatedProfileSnapshot, UserService } from "@aooth/user";
|
|
4
|
-
//#region src/errors.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Federated-login failure taxonomy (RFC IDP.md §8). Mirrors `AuthError` /
|
|
7
6
|
* `UserAuthError` — a typed `Error` with a stable `type` code, an optional
|
|
@@ -30,14 +29,12 @@ type OAuthErrorType =
|
|
|
30
29
|
"ID_TOKEN_INVALID" |
|
|
31
30
|
/** Policy needed a verified email but the provider returned none. */
|
|
32
31
|
"EMAIL_UNAVAILABLE";
|
|
33
|
-
declare class OAuthError extends Error {
|
|
32
|
+
export declare class OAuthError extends Error {
|
|
34
33
|
readonly type: OAuthErrorType;
|
|
35
34
|
readonly details?: Record<string, unknown> | undefined;
|
|
36
35
|
readonly name = "OAuthError";
|
|
37
36
|
constructor(type: OAuthErrorType, message?: string, details?: Record<string, unknown> | undefined);
|
|
38
37
|
}
|
|
39
|
-
//#endregion
|
|
40
|
-
//#region src/types.d.ts
|
|
41
38
|
/**
|
|
42
39
|
* A provider profile normalized to a single shape across Google / OIDC / etc.
|
|
43
40
|
* Structural superset of `@aooth/user`'s {@link FederatedProfileSnapshot} (the
|
|
@@ -139,7 +136,7 @@ interface ConfigurableProvider extends IdentityProvider {
|
|
|
139
136
|
applyDefaults(shared: SharedProviderConfig): void;
|
|
140
137
|
}
|
|
141
138
|
/** Structural check used by the registry to feature-detect `applyDefaults`. */
|
|
142
|
-
declare function isConfigurableProvider(p: IdentityProvider): p is ConfigurableProvider;
|
|
139
|
+
export declare function isConfigurableProvider(p: IdentityProvider): p is ConfigurableProvider;
|
|
143
140
|
/**
|
|
144
141
|
* How a federated login that matches an existing local account **by email**
|
|
145
142
|
* is handled (RFC §4 — the account-takeover-sensitive knob).
|
|
@@ -166,9 +163,9 @@ interface FederatedPolicy {
|
|
|
166
163
|
}
|
|
167
164
|
type ResolvedFederatedPolicy = Required<FederatedPolicy>;
|
|
168
165
|
/** Default username strategy: the verified email, else the stable `provider:subject`. */
|
|
169
|
-
declare function defaultUsernameStrategy(p: NormalizedProfile): string;
|
|
166
|
+
export declare function defaultUsernameStrategy(p: NormalizedProfile): string;
|
|
170
167
|
/** Apply RFC §4 safe defaults over a partial policy. */
|
|
171
|
-
declare function resolveFederatedPolicy(policy?: FederatedPolicy): ResolvedFederatedPolicy;
|
|
168
|
+
export declare function resolveFederatedPolicy(policy?: FederatedPolicy): ResolvedFederatedPolicy;
|
|
172
169
|
/**
|
|
173
170
|
* The outcome of {@link FederatedLoginService.resolveUser} (decision #1). A
|
|
174
171
|
* discriminated union — richer than the RFC's `{ userId, isNew }` sketch — so
|
|
@@ -205,8 +202,6 @@ type ResolveOutcome =
|
|
|
205
202
|
kind: "denied";
|
|
206
203
|
reason: "signup-disabled" | "email-unavailable";
|
|
207
204
|
};
|
|
208
|
-
//#endregion
|
|
209
|
-
//#region src/pkce.d.ts
|
|
210
205
|
interface PkcePair {
|
|
211
206
|
/** The high-entropy secret kept server-side (cookie / wf state). */
|
|
212
207
|
verifier: string;
|
|
@@ -229,13 +224,13 @@ interface SeededPkce {
|
|
|
229
224
|
* Mint a fresh PKCE pair. The 32-byte verifier base64url-encodes to 43 chars,
|
|
230
225
|
* comfortably inside RFC 7636's 43–128 range.
|
|
231
226
|
*/
|
|
232
|
-
declare function createPkcePair(): PkcePair;
|
|
227
|
+
export declare function createPkcePair(): PkcePair;
|
|
233
228
|
/** Recompute the S256 challenge for a known verifier (verification side). */
|
|
234
|
-
declare function pkceChallengeFor(verifier: string): string;
|
|
229
|
+
export declare function pkceChallengeFor(verifier: string): string;
|
|
235
230
|
/** OIDC `nonce` — minted at `/start`, bound into state, asserted in `exchange()`. */
|
|
236
|
-
declare function generateNonce(bytes?: number): string;
|
|
231
|
+
export declare function generateNonce(bytes?: number): string;
|
|
237
232
|
/** Random component bound into the signed `state` (anti-CSRF / anti-replay). */
|
|
238
|
-
declare function generateRandomState(bytes?: number): string;
|
|
233
|
+
export declare function generateRandomState(bytes?: number): string;
|
|
239
234
|
/**
|
|
240
235
|
* STATELESS PKCE: deterministically DERIVE the code verifier + OIDC nonce from
|
|
241
236
|
* a non-secret `seed` and the server's HMAC `secret`, instead of minting them
|
|
@@ -255,9 +250,7 @@ declare function generateRandomState(bytes?: number): string;
|
|
|
255
250
|
* Same output range as {@link createPkcePair}: a 32-byte HMAC-SHA256 digest →
|
|
256
251
|
* a 43-char base64url verifier, inside RFC 7636's 43–128.
|
|
257
252
|
*/
|
|
258
|
-
declare function deriveSeededPkce(secret: string | Uint8Array, seed: string): SeededPkce;
|
|
259
|
-
//#endregion
|
|
260
|
-
//#region src/state.d.ts
|
|
253
|
+
export declare function deriveSeededPkce(secret: string | Uint8Array, seed: string): SeededPkce;
|
|
261
254
|
/**
|
|
262
255
|
* The CSRF/replay binding carried across the OAuth bounce (RFC §7). Signed into
|
|
263
256
|
* a compact HS256 JWT by {@link signState} so it is tamper-evident in the URL
|
|
@@ -293,15 +286,13 @@ interface VerifyStateOptions {
|
|
|
293
286
|
* Sign the binding into a compact HS256 JWT. Field names are abbreviated to
|
|
294
287
|
* keep the URL `state` short; {@link verifyState} maps them back.
|
|
295
288
|
*/
|
|
296
|
-
declare function signState(payload: OAuthStatePayload, secret: string | Uint8Array, opts?: SignStateOptions): Promise<string>;
|
|
289
|
+
export declare function signState(payload: OAuthStatePayload, secret: string | Uint8Array, opts?: SignStateOptions): Promise<string>;
|
|
297
290
|
/**
|
|
298
291
|
* Verify + decode the signed state. Pins `HS256` (rejects `alg:none` / key
|
|
299
292
|
* confusion). Throws {@link OAuthError} `STATE_EXPIRED` past TTL,
|
|
300
293
|
* `STATE_INVALID` on any other signature/shape failure.
|
|
301
294
|
*/
|
|
302
|
-
declare function verifyState(token: string, secret: string | Uint8Array, opts?: VerifyStateOptions): Promise<OAuthStatePayload>;
|
|
303
|
-
//#endregion
|
|
304
|
-
//#region src/providers/oidc.d.ts
|
|
295
|
+
export declare function verifyState(token: string, secret: string | Uint8Array, opts?: VerifyStateOptions): Promise<OAuthStatePayload>;
|
|
305
296
|
/** The four endpoints the OIDC client needs — discovered or supplied explicitly. */
|
|
306
297
|
interface OidcDiscoveryDocument {
|
|
307
298
|
issuer: string;
|
|
@@ -365,7 +356,7 @@ interface OidcProviderOptions {
|
|
|
365
356
|
*
|
|
366
357
|
* `GoogleProvider` is a thin subclass pinning the issuer + algs.
|
|
367
358
|
*/
|
|
368
|
-
declare class OidcProvider implements ConfigurableProvider {
|
|
359
|
+
export declare class OidcProvider implements ConfigurableProvider {
|
|
369
360
|
readonly id: string;
|
|
370
361
|
protected readonly issuer: string;
|
|
371
362
|
protected readonly clientId: string;
|
|
@@ -413,8 +404,6 @@ declare class OidcProvider implements ConfigurableProvider {
|
|
|
413
404
|
private validateDiscovery;
|
|
414
405
|
private getJwks;
|
|
415
406
|
}
|
|
416
|
-
//#endregion
|
|
417
|
-
//#region src/providers/google.d.ts
|
|
418
407
|
/** Google options = OIDC options minus the pinned `id`/`issuer`. */
|
|
419
408
|
type GoogleProviderOptions = Omit<OidcProviderOptions, "id" | "issuer">;
|
|
420
409
|
/**
|
|
@@ -422,11 +411,9 @@ type GoogleProviderOptions = Omit<OidcProviderOptions, "id" | "issuer">;
|
|
|
422
411
|
* (Google's only ID-token alg). Everything else — discovery, JWKS rotation,
|
|
423
412
|
* the full §7 validation — is inherited from {@link OidcProvider}.
|
|
424
413
|
*/
|
|
425
|
-
declare class GoogleProvider extends OidcProvider {
|
|
414
|
+
export declare class GoogleProvider extends OidcProvider {
|
|
426
415
|
constructor(opts: GoogleProviderOptions);
|
|
427
416
|
}
|
|
428
|
-
//#endregion
|
|
429
|
-
//#region src/providers/github.d.ts
|
|
430
417
|
interface GithubProviderOptions {
|
|
431
418
|
/** Provider id. Default `'github'`. */
|
|
432
419
|
id?: string;
|
|
@@ -457,7 +444,7 @@ interface GithubProviderOptions {
|
|
|
457
444
|
* Implements {@link ConfigurableProvider} so the registry can inject a shared
|
|
458
445
|
* `fetch` (deterministic tests) / `clock`; a constructor value always wins.
|
|
459
446
|
*/
|
|
460
|
-
declare class GithubProvider implements ConfigurableProvider {
|
|
447
|
+
export declare class GithubProvider implements ConfigurableProvider {
|
|
461
448
|
readonly id: string;
|
|
462
449
|
private readonly clientId;
|
|
463
450
|
private readonly clientSecret;
|
|
@@ -486,8 +473,6 @@ declare class GithubProvider implements ConfigurableProvider {
|
|
|
486
473
|
private fetchPrimaryEmail;
|
|
487
474
|
private apiGet;
|
|
488
475
|
}
|
|
489
|
-
//#endregion
|
|
490
|
-
//#region src/providers/apple.d.ts
|
|
491
476
|
interface AppleProviderOptions extends Omit<OidcProviderOptions, "id" | "issuer" | "clientSecret" | "idTokenSigningAlgs" | "scopes"> {
|
|
492
477
|
/** The Services ID — Sign in with Apple's OAuth `client_id` (and the id_token `aud`). */
|
|
493
478
|
clientId: string;
|
|
@@ -527,15 +512,13 @@ interface AppleProviderOptions extends Omit<OidcProviderOptions, "id" | "issuer"
|
|
|
527
512
|
* capture it, so `displayName` is undefined for Apple. Collect a display name
|
|
528
513
|
* post-signup if you need one.
|
|
529
514
|
*/
|
|
530
|
-
declare class AppleProvider extends OidcProvider {
|
|
515
|
+
export declare class AppleProvider extends OidcProvider {
|
|
531
516
|
constructor(opts: AppleProviderOptions);
|
|
532
517
|
/** `email`/`name` scope makes Apple POST the callback — declare `form_post`. */
|
|
533
518
|
protected extraAuthorizationParams(_args: AuthorizationUrlArgs): Record<string, string>;
|
|
534
519
|
/** Coerce Apple's STRING `email_verified` (the base sets only a real boolean). */
|
|
535
520
|
protected normalize(payload: JWTPayload): NormalizedProfile;
|
|
536
521
|
}
|
|
537
|
-
//#endregion
|
|
538
|
-
//#region src/providers/fake.d.ts
|
|
539
522
|
interface FakeIdentityProviderOptions {
|
|
540
523
|
/** Provider id. Default `'fake'`. */
|
|
541
524
|
id?: string;
|
|
@@ -553,7 +536,7 @@ interface FakeIdentityProviderOptions {
|
|
|
553
536
|
* It does NOT verify a nonce — it is the trusted test double; the real §7
|
|
554
537
|
* nonce/JWKS assertions are exercised against {@link OidcProvider} with `jose`.
|
|
555
538
|
*/
|
|
556
|
-
declare class FakeIdentityProvider implements IdentityProvider {
|
|
539
|
+
export declare class FakeIdentityProvider implements IdentityProvider {
|
|
557
540
|
readonly id: string;
|
|
558
541
|
private readonly authorizationEndpoint;
|
|
559
542
|
private readonly defaultProfile?;
|
|
@@ -564,8 +547,6 @@ declare class FakeIdentityProvider implements IdentityProvider {
|
|
|
564
547
|
authorizationUrl(args: AuthorizationUrlArgs): Promise<string>;
|
|
565
548
|
exchange(args: ExchangeArgs): Promise<NormalizedProfile>;
|
|
566
549
|
}
|
|
567
|
-
//#endregion
|
|
568
|
-
//#region src/registry.d.ts
|
|
569
550
|
interface OAuthProviderRegistryOptions {
|
|
570
551
|
/** Public origin — `redirect_uri` is built as `baseUrl` + the callback path (§3.7). */
|
|
571
552
|
baseUrl: string;
|
|
@@ -595,7 +576,7 @@ interface OAuthProviderRegistryOptions {
|
|
|
595
576
|
* each provider that implements `applyDefaults`, and builds the per-provider
|
|
596
577
|
* fixed redirect URIs.
|
|
597
578
|
*/
|
|
598
|
-
declare class OAuthProviderRegistry {
|
|
579
|
+
export declare class OAuthProviderRegistry {
|
|
599
580
|
readonly baseUrl: string;
|
|
600
581
|
readonly stateSecret: string;
|
|
601
582
|
readonly policy: ResolvedFederatedPolicy;
|
|
@@ -628,8 +609,6 @@ declare class OAuthProviderRegistry {
|
|
|
628
609
|
*/
|
|
629
610
|
deriveSeededPkce(seed: string): SeededPkce;
|
|
630
611
|
}
|
|
631
|
-
//#endregion
|
|
632
|
-
//#region src/federated-login-service.d.ts
|
|
633
612
|
interface FederatedLoginServiceDeps<T extends object = object> {
|
|
634
613
|
/** Concrete user orchestrator (RFC: idp depends on the concrete class). */
|
|
635
614
|
users: UserService<T>;
|
|
@@ -648,7 +627,7 @@ interface FederatedLoginServiceDeps<T extends object = object> {
|
|
|
648
627
|
* Generic over the user shape `T` so a consumer's `UserService<DemoUser>` plugs
|
|
649
628
|
* in directly; `resolveUser` only reads base `UserCredentials` fields.
|
|
650
629
|
*/
|
|
651
|
-
declare class FederatedLoginService<T extends object = object> {
|
|
630
|
+
export declare class FederatedLoginService<T extends object = object> {
|
|
652
631
|
private readonly users;
|
|
653
632
|
private readonly federated;
|
|
654
633
|
readonly policy: ResolvedFederatedPolicy;
|
|
@@ -698,5 +677,4 @@ declare class FederatedLoginService<T extends object = object> {
|
|
|
698
677
|
private newIdentity;
|
|
699
678
|
private touch;
|
|
700
679
|
}
|
|
701
|
-
|
|
702
|
-
export { AppleProvider, type AppleProviderOptions, type AuthorizationUrlArgs, type ConfigurableProvider, type EmailMatchPolicy, type ExchangeArgs, FakeIdentityProvider, type FakeIdentityProviderOptions, FederatedLoginService, type FederatedLoginServiceDeps, type FederatedPolicy, type FetchLike, type FetchResponseLike, GithubProvider, type GithubProviderOptions, GoogleProvider, type GoogleProviderOptions, type IdentityProvider, type NormalizedProfile, OAuthError, type OAuthErrorType, OAuthProviderRegistry, type OAuthProviderRegistryOptions, type OAuthStatePayload, type OidcDiscoveryDocument, OidcProvider, type OidcProviderOptions, type PkcePair, type ResolveOutcome, type ResolvedFederatedPolicy, type SeededPkce, type SharedProviderConfig, type SignStateOptions, type VerifyStateOptions, createPkcePair, defaultUsernameStrategy, deriveSeededPkce, generateNonce, generateRandomState, isConfigurableProvider, pkceChallengeFor, resolveFederatedPolicy, signState, verifyState };
|
|
680
|
+
export type { AppleProviderOptions, AuthorizationUrlArgs, ConfigurableProvider, EmailMatchPolicy, ExchangeArgs, FakeIdentityProviderOptions, FederatedLoginServiceDeps, FederatedPolicy, FetchLike, FetchResponseLike, GithubProviderOptions, GoogleProviderOptions, IdentityProvider, NormalizedProfile, OAuthErrorType, OAuthProviderRegistryOptions, OAuthStatePayload, OidcDiscoveryDocument, OidcProviderOptions, PkcePair, ResolveOutcome, ResolvedFederatedPolicy, SeededPkce, SharedProviderConfig, SignStateOptions, VerifyStateOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createHash, createHmac, randomBytes } from "node:crypto";
|
|
|
2
2
|
import { defaultClock } from "@aooth/auth";
|
|
3
3
|
import { SignJWT, createRemoteJWKSet, errors, importPKCS8, jwtVerify } from "jose";
|
|
4
4
|
import { UserAuthError, pickDefinedProfile } from "@aooth/user";
|
|
5
|
-
|
|
5
|
+
// src/errors.ts
|
|
6
6
|
const defaultMessages = {
|
|
7
7
|
UNKNOWN_PROVIDER: "Unknown identity provider",
|
|
8
8
|
INVALID_CONFIG: "Invalid OAuth provider configuration",
|
|
@@ -24,8 +24,7 @@ var OAuthError = class extends Error {
|
|
|
24
24
|
this.details = details;
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
|
-
|
|
28
|
-
//#region src/types.ts
|
|
27
|
+
// src/types.ts
|
|
29
28
|
/** Structural check used by the registry to feature-detect `applyDefaults`. */
|
|
30
29
|
function isConfigurableProvider(p) {
|
|
31
30
|
return typeof p.applyDefaults === "function";
|
|
@@ -43,8 +42,7 @@ function resolveFederatedPolicy(policy = {}) {
|
|
|
43
42
|
trustEmailVerifiedFrom: policy.trustEmailVerifiedFrom ?? []
|
|
44
43
|
};
|
|
45
44
|
}
|
|
46
|
-
|
|
47
|
-
//#region src/pkce.ts
|
|
45
|
+
// src/pkce.ts
|
|
48
46
|
/**
|
|
49
47
|
* PKCE / CSRF primitives (RFC 7636 + OIDC nonce). All values are URL-safe
|
|
50
48
|
* base64url with no padding, so they ride in query params and cookies without
|
|
@@ -106,8 +104,7 @@ function deriveSeededPkce(secret, seed) {
|
|
|
106
104
|
method: "S256"
|
|
107
105
|
};
|
|
108
106
|
}
|
|
109
|
-
|
|
110
|
-
//#region src/state.ts
|
|
107
|
+
// src/state.ts
|
|
111
108
|
const DEFAULT_TTL_SEC = 600;
|
|
112
109
|
function toKey(secret) {
|
|
113
110
|
return typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
@@ -162,8 +159,7 @@ async function verifyState(token, secret, opts = {}) {
|
|
|
162
159
|
if (typeof payload.uid === "string") out.userId = payload.uid;
|
|
163
160
|
return out;
|
|
164
161
|
}
|
|
165
|
-
|
|
166
|
-
//#region src/providers/oauth2-shared.ts
|
|
162
|
+
// src/providers/oauth2-shared.ts
|
|
167
163
|
/** Resolve the effective `fetch`: an injected impl, else the global `fetch`. */
|
|
168
164
|
function resolveFetch(impl) {
|
|
169
165
|
return impl ?? globalThis.fetch;
|
|
@@ -212,8 +208,7 @@ function buildAuthorizeUrl(endpoint, args, opts = {}) {
|
|
|
212
208
|
for (const [k, v] of Object.entries(opts.extraParams ?? {})) url.searchParams.set(k, v);
|
|
213
209
|
return url.toString();
|
|
214
210
|
}
|
|
215
|
-
|
|
216
|
-
//#region src/providers/oidc.ts
|
|
211
|
+
// src/providers/oidc.ts
|
|
217
212
|
const DEFAULT_SCOPES$1 = [
|
|
218
213
|
"openid",
|
|
219
214
|
"email",
|
|
@@ -415,11 +410,11 @@ var OidcProvider = class {
|
|
|
415
410
|
* token's hash, the hash chosen by the id_token's `alg` (RS256 → SHA-256).
|
|
416
411
|
*/
|
|
417
412
|
function atHash(accessToken, alg) {
|
|
418
|
-
const
|
|
413
|
+
const sha = alg.endsWith("384") ? "sha384" : alg.endsWith("512") ? "sha512" : "sha256";
|
|
414
|
+
const digest = createHash(sha).update(accessToken).digest();
|
|
419
415
|
return digest.subarray(0, digest.length / 2).toString("base64url");
|
|
420
416
|
}
|
|
421
|
-
|
|
422
|
-
//#region src/providers/google.ts
|
|
417
|
+
// src/providers/google.ts
|
|
423
418
|
/** Google's stable OIDC issuer — endpoints + JWKS are discovered from it. */
|
|
424
419
|
const GOOGLE_ISSUER = "https://accounts.google.com";
|
|
425
420
|
/**
|
|
@@ -437,8 +432,7 @@ var GoogleProvider = class extends OidcProvider {
|
|
|
437
432
|
});
|
|
438
433
|
}
|
|
439
434
|
};
|
|
440
|
-
|
|
441
|
-
//#region src/providers/github.ts
|
|
435
|
+
// src/providers/github.ts
|
|
442
436
|
const GITHUB_AUTHORIZE = "https://github.com/login/oauth/authorize";
|
|
443
437
|
const GITHUB_TOKEN = "https://github.com/login/oauth/access_token";
|
|
444
438
|
const GITHUB_USER = "https://api.github.com/user";
|
|
@@ -575,8 +569,7 @@ var GithubProvider = class {
|
|
|
575
569
|
}, { label: `GitHub API (${url})` });
|
|
576
570
|
}
|
|
577
571
|
};
|
|
578
|
-
|
|
579
|
-
//#region src/providers/apple.ts
|
|
572
|
+
// src/providers/apple.ts
|
|
580
573
|
/** Apple's stable OIDC issuer — endpoints + JWKS are discovered from it. */
|
|
581
574
|
const APPLE_ISSUER = "https://appleid.apple.com";
|
|
582
575
|
/** Apple ID tokens are always ES256. */
|
|
@@ -680,8 +673,7 @@ var AppleProvider = class extends OidcProvider {
|
|
|
680
673
|
return profile;
|
|
681
674
|
}
|
|
682
675
|
};
|
|
683
|
-
|
|
684
|
-
//#region src/providers/fake.ts
|
|
676
|
+
// src/providers/fake.ts
|
|
685
677
|
/**
|
|
686
678
|
* Deterministic, network-free {@link IdentityProvider} for unit tests and the
|
|
687
679
|
* `DEMO_MODE=test` fake-IdP e2e route (RFC §9). `exchange` resolves a `code`
|
|
@@ -718,8 +710,7 @@ var FakeIdentityProvider = class {
|
|
|
718
710
|
});
|
|
719
711
|
}
|
|
720
712
|
};
|
|
721
|
-
|
|
722
|
-
//#region src/registry.ts
|
|
713
|
+
// src/registry.ts
|
|
723
714
|
const DEFAULT_CALLBACK_TEMPLATE = "/auth/oauth/:provider/callback";
|
|
724
715
|
/**
|
|
725
716
|
* Holds the configured {@link IdentityProvider}s + {@link FederatedPolicy} +
|
|
@@ -801,8 +792,7 @@ var OAuthProviderRegistry = class {
|
|
|
801
792
|
return deriveSeededPkce(this.stateSecret, seed);
|
|
802
793
|
}
|
|
803
794
|
};
|
|
804
|
-
|
|
805
|
-
//#region src/federated-login-service.ts
|
|
795
|
+
// src/federated-login-service.ts
|
|
806
796
|
/**
|
|
807
797
|
* The core federated-login logic (RFC §3.5): map a verified provider profile to
|
|
808
798
|
* an aooth user id. Pure orchestration over `UserService` + `FederatedIdentityStore`
|
|
@@ -939,5 +929,4 @@ var FederatedLoginService = class {
|
|
|
939
929
|
return this.federated.touchLogin(profile.provider, profile.subject, pickDefinedProfile(profile));
|
|
940
930
|
}
|
|
941
931
|
};
|
|
942
|
-
//#endregion
|
|
943
932
|
export { AppleProvider, FakeIdentityProvider, FederatedLoginService, GithubProvider, GoogleProvider, OAuthError, OAuthProviderRegistry, OidcProvider, createPkcePair, defaultUsernameStrategy, deriveSeededPkce, generateNonce, generateRandomState, isConfigurableProvider, pkceChallengeFor, resolveFederatedPolicy, signState, verifyState };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aooth/idp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Framework-agnostic OAuth2 / OIDC federated-login core for aoothjs (provider registry, PKCE/state, ID-token verification, account resolution)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aoothjs",
|
|
@@ -43,12 +43,10 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"jose": "^6.2.3",
|
|
46
|
-
"@aooth/auth": "0.2.
|
|
47
|
-
"@aooth/user": "0.2.
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
|
46
|
+
"@aooth/auth": "0.2.2",
|
|
47
|
+
"@aooth/user": "0.2.2"
|
|
51
48
|
},
|
|
49
|
+
"devDependencies": {},
|
|
52
50
|
"scripts": {
|
|
53
51
|
"build": "vp pack",
|
|
54
52
|
"dev": "vp pack --watch",
|