@azlib/identity 0.2.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.
Files changed (69) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +387 -0
  3. package/dist/errors-BGMwaW5s.d.mts +481 -0
  4. package/dist/errors-BGMwaW5s.d.mts.map +1 -0
  5. package/dist/errors-Bcjx9o6g.cjs +111 -0
  6. package/dist/errors-C2xZAatu.d.cts +481 -0
  7. package/dist/errors-C2xZAatu.d.cts.map +1 -0
  8. package/dist/errors-CEmnZxIn.mjs +66 -0
  9. package/dist/errors-CEmnZxIn.mjs.map +1 -0
  10. package/dist/express.cjs +405 -0
  11. package/dist/express.d.cts +87 -0
  12. package/dist/express.d.cts.map +1 -0
  13. package/dist/express.d.mts +87 -0
  14. package/dist/express.d.mts.map +1 -0
  15. package/dist/express.mjs +401 -0
  16. package/dist/express.mjs.map +1 -0
  17. package/dist/identity-4eP45YIP.cjs +461 -0
  18. package/dist/identity-Bz9RDOvT.mjs +410 -0
  19. package/dist/identity-Bz9RDOvT.mjs.map +1 -0
  20. package/dist/identity-router-DBL20UWT.d.mts +115 -0
  21. package/dist/identity-router-DBL20UWT.d.mts.map +1 -0
  22. package/dist/identity-router-Dib30Waj.d.cts +115 -0
  23. package/dist/identity-router-Dib30Waj.d.cts.map +1 -0
  24. package/dist/identity-service-B9zrvE9z.d.mts +128 -0
  25. package/dist/identity-service-B9zrvE9z.d.mts.map +1 -0
  26. package/dist/identity-service-CLzKx8Z7.d.cts +128 -0
  27. package/dist/identity-service-CLzKx8Z7.d.cts.map +1 -0
  28. package/dist/identity-store-BRRahxcS.d.cts +272 -0
  29. package/dist/identity-store-BRRahxcS.d.cts.map +1 -0
  30. package/dist/identity-store-BRRahxcS.d.mts +272 -0
  31. package/dist/identity-store-BRRahxcS.d.mts.map +1 -0
  32. package/dist/index-CpufYgyn.d.cts +30 -0
  33. package/dist/index-CpufYgyn.d.cts.map +1 -0
  34. package/dist/index-CpufYgyn.d.mts +30 -0
  35. package/dist/index-CpufYgyn.d.mts.map +1 -0
  36. package/dist/index.cjs +18 -0
  37. package/dist/index.d.cts +4 -0
  38. package/dist/index.d.mts +4 -0
  39. package/dist/index.mjs +3 -0
  40. package/dist/logger-Be1wDzBC.cjs +48 -0
  41. package/dist/logger-CcCHJVVe.mjs +33 -0
  42. package/dist/logger-CcCHJVVe.mjs.map +1 -0
  43. package/dist/nestjs.cjs +516 -0
  44. package/dist/nestjs.d.cts +102 -0
  45. package/dist/nestjs.d.cts.map +1 -0
  46. package/dist/nestjs.d.mts +102 -0
  47. package/dist/nestjs.d.mts.map +1 -0
  48. package/dist/nestjs.mjs +500 -0
  49. package/dist/nestjs.mjs.map +1 -0
  50. package/dist/node.cjs +946 -0
  51. package/dist/node.d.cts +260 -0
  52. package/dist/node.d.cts.map +1 -0
  53. package/dist/node.d.mts +260 -0
  54. package/dist/node.d.mts.map +1 -0
  55. package/dist/node.mjs +890 -0
  56. package/dist/node.mjs.map +1 -0
  57. package/dist/test-utils.cjs +169 -0
  58. package/dist/test-utils.d.cts +12 -0
  59. package/dist/test-utils.d.cts.map +1 -0
  60. package/dist/test-utils.d.mts +12 -0
  61. package/dist/test-utils.d.mts.map +1 -0
  62. package/dist/test-utils.mjs +170 -0
  63. package/dist/test-utils.mjs.map +1 -0
  64. package/package.json +92 -0
  65. package/schema/model.ts +100 -0
  66. package/schema/mysql.sql +102 -0
  67. package/schema/postgres.sql +92 -0
  68. package/schema/prisma.schema +122 -0
  69. package/schema/sqlite.sql +92 -0
@@ -0,0 +1,115 @@
1
+ import { F as IdentityLogger } from "./errors-C2xZAatu.cjs";
2
+ import { t as IdentityService } from "./identity-service-CLzKx8Z7.cjs";
3
+ import { Request, Response, Router } from "express";
4
+
5
+ //#region core/express/identity-router.d.ts
6
+ /** Options for controlling the refresh-token cookie. */
7
+ interface CookieRefreshOptions {
8
+ /** Cookie name. Default: `"azlib_rt"`. */
9
+ name?: string;
10
+ /** Mark the cookie as `HttpOnly`. Default: `true`. */
11
+ httpOnly?: boolean;
12
+ /**
13
+ * Mark the cookie as `Secure`. Defaults to `true` when `NODE_ENV` is `"production"`,
14
+ * `false` otherwise.
15
+ */
16
+ secure?: boolean;
17
+ /** `SameSite` policy. Default: `"lax"`. */
18
+ sameSite?: "strict" | "lax" | "none";
19
+ /** Cookie path. Default: `"/"`. */
20
+ path?: string;
21
+ /** Cookie domain. Omit to use the current host. */
22
+ domain?: string;
23
+ }
24
+ /**
25
+ * Options for {@link createIdentityRouter}.
26
+ */
27
+ interface IdentityRouterOptions {
28
+ /**
29
+ * Controls how the refresh token is transported between server and client.
30
+ *
31
+ * - **`"body"`** (default) — the refresh token is included in the `tokens` object of
32
+ * every successful `register`/`login`/`refresh` response. The client must store it
33
+ * and send it back via the JSON body on `/refresh` and `/logout`.
34
+ *
35
+ * - **`{ cookie: CookieRefreshOptions }`** — the refresh token is sent as an
36
+ * `HttpOnly` cookie. `/refresh` and `/logout` read it automatically; the response
37
+ * body only includes the access token.
38
+ */
39
+ refreshToken?: "body" | {
40
+ cookie: CookieRefreshOptions;
41
+ };
42
+ /**
43
+ * Base URL under which the OAuth callback routes are hosted.
44
+ *
45
+ * Example: `"https://api.example.com/auth"`.
46
+ *
47
+ * The callback URI for a provider becomes `{oauthBaseUrl}/{providerName}/callback`.
48
+ * Required when the identity service has OAuth providers configured.
49
+ */
50
+ oauthBaseUrl?: string;
51
+ /**
52
+ * URL path prefix prepended to all identity routes.
53
+ *
54
+ * Default: `"account"`. Routes are served at `/{prefix}/login`, `/{prefix}/register`, etc.
55
+ *
56
+ * Mount the returned router at the application root:
57
+ * ```ts
58
+ * app.use(createIdentityRouter(service, { prefix: "auth" }));
59
+ * // → POST /auth/login, POST /auth/register, …
60
+ * ```
61
+ *
62
+ * Set to `""` to omit the prefix and mount routes directly at the router's mount point.
63
+ */
64
+ prefix?: string;
65
+ /**
66
+ * Logger for request/response and error diagnostics.
67
+ *
68
+ * - Omit — defaults to a `console`-based logger with an `[identity]` prefix.
69
+ * - Supply your own `IdentityLogger` — route output to Winston, Pino, etc.
70
+ * - Pass `false` — disable all logging from this router.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * import pino from "pino";
75
+ * app.use(createIdentityRouter(service, { logger: pino() }));
76
+ * ```
77
+ */
78
+ logger?: IdentityLogger | false;
79
+ }
80
+ /**
81
+ * Creates a pre-wired Express `Router` with all standard identity endpoints.
82
+ *
83
+ * Mount it once on your application:
84
+ * ```ts
85
+ * import express from "express";
86
+ * import { createIdentityService } from "@azlib/identity/node";
87
+ * import { createIdentityRouter, identityErrorHandler } from "@azlib/identity/express";
88
+ *
89
+ * const service = createIdentityService(config, store);
90
+ * const app = express();
91
+ *
92
+ * app.use(express.json());
93
+ * // Routes are served at /account/login, /account/register, etc. (default prefix)
94
+ * app.use(createIdentityRouter(service));
95
+ * // Or use a custom prefix:
96
+ * app.use(createIdentityRouter(service, { prefix: "auth" }));
97
+ * app.use(identityErrorHandler()); // optional convenience error handler
98
+ * ```
99
+ *
100
+ * Pre-wired routes:
101
+ *
102
+ * | Method | Path | Description |
103
+ * |--------|------|-------------|
104
+ * | POST | `/register` | Create a new account |
105
+ * | POST | `/login` | Email + password login |
106
+ * | POST | `/refresh` | Rotate the refresh token |
107
+ * | POST | `/logout` | Revoke the current session |
108
+ * | GET | `/me` | Return the authenticated principal |
109
+ * | GET | `/:provider` | Start an OAuth 2.0 authorisation flow *(optional)* |
110
+ * | GET | `/:provider/callback` | Handle an OAuth 2.0 callback *(optional)* |
111
+ */
112
+ declare function createIdentityRouter(service: IdentityService, options?: IdentityRouterOptions): Router;
113
+ //#endregion
114
+ export { IdentityRouterOptions as n, createIdentityRouter as r, CookieRefreshOptions as t };
115
+ //# sourceMappingURL=identity-router-Dib30Waj.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-router-Dib30Waj.d.cts","names":[],"sources":["../core/express/identity-router.ts"],"mappings":";;;;;;UAeiB,oBAAA;EAAA;EAEf,IAAA;;EAEA,QAAA;EAFA;;;;EAOA,MAAA;EAMA;EAJA,QAAA;EAIM;EAFN,IAAA;EAQoC;EANpC,MAAA;AAAA;;;;UAMe,qBAAA;EAqCf;;;;AAeuB;AAsIzB;;;;;;EA9KE,YAAA;IAA0B,MAAA,EAAQ,oBAAA;EAAA;EA+KlC;;;;;AAEO;;;EAvKP,YAAA;;;;;;;;;;;;;;EAeA,MAAA;;;;;;;;;;;;;;EAeA,MAAA,GAAS,cAAc;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsIT,oBAAA,CACd,OAAA,EAAS,eAAA,EACT,OAAA,GAAS,qBAAA,GACR,MAAA"}
@@ -0,0 +1,128 @@
1
+ import { T as TotpSetupResult, c as AuthResult, d as AuthenticatedIdentity, r as IdentityStore, v as LoginResult } from "./identity-store-BRRahxcS.mjs";
2
+ import { B as AuthorizationDecision, D as IdentityConfigInput, V as AuthorizationRequirement, a as IdentityError, f as OAuthService, v as OAuthProvider, w as AuditLogger, x as SessionDeps, z as AuthorizationContext } from "./errors-BGMwaW5s.mjs";
3
+
4
+ //#region core/password-hasher.d.ts
5
+ interface PasswordHasher {
6
+ hash(password: string): Promise<string>;
7
+ verify(password: string, storedHash: string): Promise<boolean>;
8
+ }
9
+ /** Creates a scrypt-based {@link PasswordHasher}. */
10
+ declare function createPasswordHasher(cost: number): PasswordHasher;
11
+ //#endregion
12
+ //#region core/login.d.ts
13
+ /** Dependencies for the login flow. */
14
+ interface LoginDeps extends SessionDeps {
15
+ hasher: PasswordHasher;
16
+ audit: AuditLogger;
17
+ }
18
+ /** Input for {@link loginUser}. */
19
+ interface LoginInput {
20
+ email: string;
21
+ password: string;
22
+ }
23
+ /**
24
+ * Authenticates a user with email + password. Uses a single generic failure for both
25
+ * "unknown user" and "wrong password" to avoid account enumeration, and performs a hash
26
+ * comparison even when the user is unknown to reduce timing side-channels.
27
+ *
28
+ * When account lockout is enabled (config.lockout.maxFailedAttempts > 0), consecutive
29
+ * failures increment a counter and temporarily lock the account.
30
+ */
31
+ declare function loginUser(deps: LoginDeps, input: LoginInput): Promise<LoginResult>;
32
+ //#endregion
33
+ //#region core/register.d.ts
34
+ /** Dependencies for the register flow. */
35
+ interface RegisterDeps extends SessionDeps {
36
+ hasher: PasswordHasher;
37
+ audit: AuditLogger;
38
+ }
39
+ /** Input for {@link registerUser}. */
40
+ interface RegisterInput {
41
+ email: string;
42
+ password: string;
43
+ displayName?: string | null;
44
+ }
45
+ /** Raised when registration input fails validation. */
46
+ declare class RegistrationValidationError extends IdentityError {
47
+ constructor(message: string);
48
+ }
49
+ /** Normalizes an email for storage and lookup (trim + lowercase). */
50
+ declare function normalizeEmail(email: string): string;
51
+ /**
52
+ * Registers a new user: validates input, enforces unique email, hashes the password,
53
+ * persists the user and credential, and returns an authenticated session.
54
+ */
55
+ declare function registerUser(deps: RegisterDeps, input: RegisterInput): Promise<AuthResult>;
56
+ //#endregion
57
+ //#region core/identity-service.d.ts
58
+ /** The wired runtime API returned by {@link createIdentityService}. */
59
+ interface IdentityService {
60
+ register(input: RegisterInput): Promise<AuthResult>;
61
+ /**
62
+ * Authenticates with email + password. Returns a full {@link AuthResult} normally, or
63
+ * an {@link MfaRequiredResult} (containing an `mfaToken`) when the account has 2FA
64
+ * enabled. In the latter case call {@link verifyMfaChallenge} to complete the login.
65
+ */
66
+ login(input: LoginInput): Promise<LoginResult>;
67
+ refresh(refreshToken: string): Promise<AuthResult>;
68
+ logout(refreshToken: string): Promise<void>;
69
+ /**
70
+ * Verifies an access token and hydrates the current principal from the store.
71
+ * Throws {@link InvalidTokenError} for invalid/stale tokens.
72
+ */
73
+ authenticate(accessToken: string): Promise<AuthenticatedIdentity>;
74
+ authorize<TResource = unknown>(requirement: AuthorizationRequirement<TResource>, context: AuthorizationContext<TResource>): Promise<AuthorizationDecision>;
75
+ /** Sends (or resends) an email verification link for the given user id. */
76
+ requestEmailVerification(userId: string): Promise<void>;
77
+ /** Marks the user's email as verified using the token from the verification link. */
78
+ verifyEmail(token: string): Promise<void>;
79
+ /** Sends a password reset link to the given email address. Silent for unknown addresses. */
80
+ requestPasswordReset(email: string): Promise<void>;
81
+ /** Resets the password using the token from the reset link. */
82
+ resetPassword(token: string, newPassword: string): Promise<void>;
83
+ /**
84
+ * Begins the 2FA setup flow. Returns the TOTP secret and an OTP Auth URI for QR code
85
+ * display. Call {@link enable2FA} with a valid code to activate.
86
+ */
87
+ setup2FA(userId: string): Promise<TotpSetupResult>;
88
+ /** Confirms and enables 2FA. Requires a valid TOTP code from the authenticator app. */
89
+ enable2FA(userId: string, totpCode: string): Promise<void>;
90
+ /** Disables 2FA. Requires a valid TOTP code as confirmation. */
91
+ disable2FA(userId: string, totpCode: string): Promise<void>;
92
+ /**
93
+ * Completes an MFA challenge. Present the `mfaToken` returned by `login` together
94
+ * with the TOTP code from the authenticator app.
95
+ */
96
+ verifyMfaChallenge(mfaToken: string, totpCode: string): Promise<AuthResult>;
97
+ /** Locks the account and revokes all active sessions. */
98
+ lockAccount(userId: string): Promise<void>;
99
+ /** Unlocks the account and clears lockout state. */
100
+ unlockAccount(userId: string): Promise<void>;
101
+ /** Permanently disables the account (requires manual admin unlock). */
102
+ disableAccount(userId: string): Promise<void>;
103
+ /**
104
+ * The OAuth 2.0 / OpenID Connect surface. Present only when at least one provider is
105
+ * configured via `IdentityConfigInput.oauth.providers`.
106
+ */
107
+ oauth?: OAuthService;
108
+ }
109
+ /** Extended config input with optional OAuth provider list. */
110
+ interface IdentityServiceConfig extends IdentityConfigInput {
111
+ /** Optional OAuth 2.0 / OIDC configuration. */
112
+ oauth?: {
113
+ /**
114
+ * The list of external authentication providers to enable. Each item is an
115
+ * {@link OAuthProvider} instance, e.g. `createGoogleOAuthProvider(...)` or
116
+ * `createMicrosoftOAuthProvider(...)`.
117
+ */
118
+ providers: OAuthProvider[];
119
+ };
120
+ }
121
+ /**
122
+ * Wires the framework-agnostic identity runtime with Node defaults (scrypt hashing,
123
+ * `jose` HS256 tokens). Express and NestJS adapters build on top of this service.
124
+ */
125
+ declare function createIdentityService(configInput: IdentityServiceConfig, store: IdentityStore): IdentityService;
126
+ //#endregion
127
+ export { RegisterInput as a, registerUser as c, loginUser as d, PasswordHasher as f, RegisterDeps as i, LoginDeps as l, IdentityServiceConfig as n, RegistrationValidationError as o, createPasswordHasher as p, createIdentityService as r, normalizeEmail as s, IdentityService as t, LoginInput as u };
128
+ //# sourceMappingURL=identity-service-B9zrvE9z.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-service-B9zrvE9z.d.mts","names":[],"sources":["../core/password-hasher.ts","../core/login.ts","../core/register.ts","../core/identity-service.ts"],"mappings":";;;;UAuBiB,cAAA;EACf,IAAA,CAAK,QAAA,WAAmB,OAAA;EACxB,MAAA,CAAO,QAAA,UAAkB,UAAA,WAAqB,OAAO;AAAA;AAFvD;AAAA,iBAMgB,oBAAA,CAAqB,IAAA,WAAe,cAAc;;;AANlE;AAAA,UCbiB,SAAA,SAAkB,WAAA;EACjC,MAAA,EAAQ,cAAA;EACR,KAAA,EAAO,WAAA;AAAA;;UAIQ,UAAA;EACf,KAAA;EACA,QAAQ;AAAA;;;ADO6C;AAIvD;;;;AAAkE;iBCA5C,SAAA,CAAU,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,UAAA,GAAa,OAAA,CAAQ,WAAA;;;;UCtB5D,YAAA,SAAqB,WAAA;EACpC,MAAA,EAAQ,cAAA;EACR,KAAA,EAAO,WAAA;AAAA;;UAIQ,aAAA;EACf,KAAA;EACA,QAAA;EACA,WAAA;AAAA;AFSqD;AAAA,cEL1C,2BAAA,SAAoC,aAAa;cAChD,OAAA;AAAA;;iBASE,cAAA,CAAe,KAAa;;;;ADpB5C;iBC4BsB,YAAA,CACpB,IAAA,EAAM,YAAA,EACN,KAAA,EAAO,aAAA,GACN,OAAA,CAAQ,UAAA;;;;UCDM,eAAA;EACf,QAAA,CAAS,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,UAAA;EHhBxC;;;;;EGsBA,KAAA,CAAM,KAAA,EAAO,UAAA,GAAa,OAAA,CAAQ,WAAA;EAClC,OAAA,CAAQ,YAAA,WAAuB,OAAA,CAAQ,UAAA;EACvC,MAAA,CAAO,YAAA,WAAuB,OAAA;;;AHpBkC;;EGyBhE,YAAA,CAAa,WAAA,WAAsB,OAAA,CAAQ,qBAAA;EAC3C,SAAA,sBACE,WAAA,EAAa,wBAAA,CAAyB,SAAA,GACtC,OAAA,EAAS,oBAAA,CAAqB,SAAA,IAC7B,OAAA,CAAQ,qBAAA;EFhDI;EEoDf,wBAAA,CAAyB,MAAA,WAAiB,OAAA;;EAE1C,WAAA,CAAY,KAAA,WAAgB,OAAA;EFpDrB;EEwDP,oBAAA,CAAqB,KAAA,WAAgB,OAAA;EF1DO;EE4D5C,aAAA,CAAc,KAAA,UAAe,WAAA,WAAsB,OAAA;EF5DlB;;;;EEmEjC,QAAA,CAAS,MAAA,WAAiB,OAAA,CAAQ,eAAA;EFjEhB;EEmElB,SAAA,CAAU,MAAA,UAAgB,QAAA,WAAmB,OAAA;EF/D9B;EEiEf,UAAA,CAAW,MAAA,UAAgB,QAAA,WAAmB,OAAA;;;AF/DtC;AAWV;EEyDE,kBAAA,CAAmB,QAAA,UAAkB,QAAA,WAAmB,OAAA,CAAQ,UAAA;;EAIhE,WAAA,CAAY,MAAA,WAAiB,OAAA;EF7DyB;EE+DtD,aAAA,CAAc,MAAA,WAAiB,OAAA;EF/DoC;EEiEnE,cAAA,CAAe,MAAA,WAAiB,OAAA;EFjE0C;;;;EEuE1E,KAAA,GAAQ,YAAA;AAAA;;UAIO,qBAAA,SAA8B,mBAAmB;EF3EsB;EE6EtF,KAAA;;;ADnGF;;;ICyGI,SAAA,EAAW,aAAA;EAAA;AAAA;;;;;iBAQC,qBAAA,CACd,WAAA,EAAa,qBAAA,EACb,KAAA,EAAO,aAAA,GACN,eAAA"}
@@ -0,0 +1,128 @@
1
+ import { T as TotpSetupResult, c as AuthResult, d as AuthenticatedIdentity, r as IdentityStore, v as LoginResult } from "./identity-store-BRRahxcS.cjs";
2
+ import { B as AuthorizationDecision, D as IdentityConfigInput, V as AuthorizationRequirement, a as IdentityError, f as OAuthService, v as OAuthProvider, w as AuditLogger, x as SessionDeps, z as AuthorizationContext } from "./errors-C2xZAatu.cjs";
3
+
4
+ //#region core/password-hasher.d.ts
5
+ interface PasswordHasher {
6
+ hash(password: string): Promise<string>;
7
+ verify(password: string, storedHash: string): Promise<boolean>;
8
+ }
9
+ /** Creates a scrypt-based {@link PasswordHasher}. */
10
+ declare function createPasswordHasher(cost: number): PasswordHasher;
11
+ //#endregion
12
+ //#region core/login.d.ts
13
+ /** Dependencies for the login flow. */
14
+ interface LoginDeps extends SessionDeps {
15
+ hasher: PasswordHasher;
16
+ audit: AuditLogger;
17
+ }
18
+ /** Input for {@link loginUser}. */
19
+ interface LoginInput {
20
+ email: string;
21
+ password: string;
22
+ }
23
+ /**
24
+ * Authenticates a user with email + password. Uses a single generic failure for both
25
+ * "unknown user" and "wrong password" to avoid account enumeration, and performs a hash
26
+ * comparison even when the user is unknown to reduce timing side-channels.
27
+ *
28
+ * When account lockout is enabled (config.lockout.maxFailedAttempts > 0), consecutive
29
+ * failures increment a counter and temporarily lock the account.
30
+ */
31
+ declare function loginUser(deps: LoginDeps, input: LoginInput): Promise<LoginResult>;
32
+ //#endregion
33
+ //#region core/register.d.ts
34
+ /** Dependencies for the register flow. */
35
+ interface RegisterDeps extends SessionDeps {
36
+ hasher: PasswordHasher;
37
+ audit: AuditLogger;
38
+ }
39
+ /** Input for {@link registerUser}. */
40
+ interface RegisterInput {
41
+ email: string;
42
+ password: string;
43
+ displayName?: string | null;
44
+ }
45
+ /** Raised when registration input fails validation. */
46
+ declare class RegistrationValidationError extends IdentityError {
47
+ constructor(message: string);
48
+ }
49
+ /** Normalizes an email for storage and lookup (trim + lowercase). */
50
+ declare function normalizeEmail(email: string): string;
51
+ /**
52
+ * Registers a new user: validates input, enforces unique email, hashes the password,
53
+ * persists the user and credential, and returns an authenticated session.
54
+ */
55
+ declare function registerUser(deps: RegisterDeps, input: RegisterInput): Promise<AuthResult>;
56
+ //#endregion
57
+ //#region core/identity-service.d.ts
58
+ /** The wired runtime API returned by {@link createIdentityService}. */
59
+ interface IdentityService {
60
+ register(input: RegisterInput): Promise<AuthResult>;
61
+ /**
62
+ * Authenticates with email + password. Returns a full {@link AuthResult} normally, or
63
+ * an {@link MfaRequiredResult} (containing an `mfaToken`) when the account has 2FA
64
+ * enabled. In the latter case call {@link verifyMfaChallenge} to complete the login.
65
+ */
66
+ login(input: LoginInput): Promise<LoginResult>;
67
+ refresh(refreshToken: string): Promise<AuthResult>;
68
+ logout(refreshToken: string): Promise<void>;
69
+ /**
70
+ * Verifies an access token and hydrates the current principal from the store.
71
+ * Throws {@link InvalidTokenError} for invalid/stale tokens.
72
+ */
73
+ authenticate(accessToken: string): Promise<AuthenticatedIdentity>;
74
+ authorize<TResource = unknown>(requirement: AuthorizationRequirement<TResource>, context: AuthorizationContext<TResource>): Promise<AuthorizationDecision>;
75
+ /** Sends (or resends) an email verification link for the given user id. */
76
+ requestEmailVerification(userId: string): Promise<void>;
77
+ /** Marks the user's email as verified using the token from the verification link. */
78
+ verifyEmail(token: string): Promise<void>;
79
+ /** Sends a password reset link to the given email address. Silent for unknown addresses. */
80
+ requestPasswordReset(email: string): Promise<void>;
81
+ /** Resets the password using the token from the reset link. */
82
+ resetPassword(token: string, newPassword: string): Promise<void>;
83
+ /**
84
+ * Begins the 2FA setup flow. Returns the TOTP secret and an OTP Auth URI for QR code
85
+ * display. Call {@link enable2FA} with a valid code to activate.
86
+ */
87
+ setup2FA(userId: string): Promise<TotpSetupResult>;
88
+ /** Confirms and enables 2FA. Requires a valid TOTP code from the authenticator app. */
89
+ enable2FA(userId: string, totpCode: string): Promise<void>;
90
+ /** Disables 2FA. Requires a valid TOTP code as confirmation. */
91
+ disable2FA(userId: string, totpCode: string): Promise<void>;
92
+ /**
93
+ * Completes an MFA challenge. Present the `mfaToken` returned by `login` together
94
+ * with the TOTP code from the authenticator app.
95
+ */
96
+ verifyMfaChallenge(mfaToken: string, totpCode: string): Promise<AuthResult>;
97
+ /** Locks the account and revokes all active sessions. */
98
+ lockAccount(userId: string): Promise<void>;
99
+ /** Unlocks the account and clears lockout state. */
100
+ unlockAccount(userId: string): Promise<void>;
101
+ /** Permanently disables the account (requires manual admin unlock). */
102
+ disableAccount(userId: string): Promise<void>;
103
+ /**
104
+ * The OAuth 2.0 / OpenID Connect surface. Present only when at least one provider is
105
+ * configured via `IdentityConfigInput.oauth.providers`.
106
+ */
107
+ oauth?: OAuthService;
108
+ }
109
+ /** Extended config input with optional OAuth provider list. */
110
+ interface IdentityServiceConfig extends IdentityConfigInput {
111
+ /** Optional OAuth 2.0 / OIDC configuration. */
112
+ oauth?: {
113
+ /**
114
+ * The list of external authentication providers to enable. Each item is an
115
+ * {@link OAuthProvider} instance, e.g. `createGoogleOAuthProvider(...)` or
116
+ * `createMicrosoftOAuthProvider(...)`.
117
+ */
118
+ providers: OAuthProvider[];
119
+ };
120
+ }
121
+ /**
122
+ * Wires the framework-agnostic identity runtime with Node defaults (scrypt hashing,
123
+ * `jose` HS256 tokens). Express and NestJS adapters build on top of this service.
124
+ */
125
+ declare function createIdentityService(configInput: IdentityServiceConfig, store: IdentityStore): IdentityService;
126
+ //#endregion
127
+ export { RegisterInput as a, registerUser as c, loginUser as d, PasswordHasher as f, RegisterDeps as i, LoginDeps as l, IdentityServiceConfig as n, RegistrationValidationError as o, createPasswordHasher as p, createIdentityService as r, normalizeEmail as s, IdentityService as t, LoginInput as u };
128
+ //# sourceMappingURL=identity-service-CLzKx8Z7.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-service-CLzKx8Z7.d.cts","names":[],"sources":["../core/password-hasher.ts","../core/login.ts","../core/register.ts","../core/identity-service.ts"],"mappings":";;;;UAuBiB,cAAA;EACf,IAAA,CAAK,QAAA,WAAmB,OAAA;EACxB,MAAA,CAAO,QAAA,UAAkB,UAAA,WAAqB,OAAO;AAAA;AAFvD;AAAA,iBAMgB,oBAAA,CAAqB,IAAA,WAAe,cAAc;;;AANlE;AAAA,UCbiB,SAAA,SAAkB,WAAA;EACjC,MAAA,EAAQ,cAAA;EACR,KAAA,EAAO,WAAA;AAAA;;UAIQ,UAAA;EACf,KAAA;EACA,QAAQ;AAAA;;;ADO6C;AAIvD;;;;AAAkE;iBCA5C,SAAA,CAAU,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,UAAA,GAAa,OAAA,CAAQ,WAAA;;;;UCtB5D,YAAA,SAAqB,WAAA;EACpC,MAAA,EAAQ,cAAA;EACR,KAAA,EAAO,WAAA;AAAA;;UAIQ,aAAA;EACf,KAAA;EACA,QAAA;EACA,WAAA;AAAA;AFSqD;AAAA,cEL1C,2BAAA,SAAoC,aAAa;cAChD,OAAA;AAAA;;iBASE,cAAA,CAAe,KAAa;;;;ADpB5C;iBC4BsB,YAAA,CACpB,IAAA,EAAM,YAAA,EACN,KAAA,EAAO,aAAA,GACN,OAAA,CAAQ,UAAA;;;;UCDM,eAAA;EACf,QAAA,CAAS,KAAA,EAAO,aAAA,GAAgB,OAAA,CAAQ,UAAA;EHhBxC;;;;;EGsBA,KAAA,CAAM,KAAA,EAAO,UAAA,GAAa,OAAA,CAAQ,WAAA;EAClC,OAAA,CAAQ,YAAA,WAAuB,OAAA,CAAQ,UAAA;EACvC,MAAA,CAAO,YAAA,WAAuB,OAAA;;;AHpBkC;;EGyBhE,YAAA,CAAa,WAAA,WAAsB,OAAA,CAAQ,qBAAA;EAC3C,SAAA,sBACE,WAAA,EAAa,wBAAA,CAAyB,SAAA,GACtC,OAAA,EAAS,oBAAA,CAAqB,SAAA,IAC7B,OAAA,CAAQ,qBAAA;EFhDI;EEoDf,wBAAA,CAAyB,MAAA,WAAiB,OAAA;;EAE1C,WAAA,CAAY,KAAA,WAAgB,OAAA;EFpDrB;EEwDP,oBAAA,CAAqB,KAAA,WAAgB,OAAA;EF1DO;EE4D5C,aAAA,CAAc,KAAA,UAAe,WAAA,WAAsB,OAAA;EF5DlB;;;;EEmEjC,QAAA,CAAS,MAAA,WAAiB,OAAA,CAAQ,eAAA;EFjEhB;EEmElB,SAAA,CAAU,MAAA,UAAgB,QAAA,WAAmB,OAAA;EF/D9B;EEiEf,UAAA,CAAW,MAAA,UAAgB,QAAA,WAAmB,OAAA;;;AF/DtC;AAWV;EEyDE,kBAAA,CAAmB,QAAA,UAAkB,QAAA,WAAmB,OAAA,CAAQ,UAAA;;EAIhE,WAAA,CAAY,MAAA,WAAiB,OAAA;EF7DyB;EE+DtD,aAAA,CAAc,MAAA,WAAiB,OAAA;EF/DoC;EEiEnE,cAAA,CAAe,MAAA,WAAiB,OAAA;EFjE0C;;;;EEuE1E,KAAA,GAAQ,YAAA;AAAA;;UAIO,qBAAA,SAA8B,mBAAmB;EF3EsB;EE6EtF,KAAA;;;ADnGF;;;ICyGI,SAAA,EAAW,aAAA;EAAA;AAAA;;;;;iBAQC,qBAAA,CACd,WAAA,EAAa,qBAAA,EACb,KAAA,EAAO,aAAA,GACN,eAAA"}
@@ -0,0 +1,272 @@
1
+ //#region core/types.d.ts
2
+ /**
3
+ * Shared, framework-agnostic domain types for `@azlib/identity`.
4
+ *
5
+ * These types describe the persistence model and the runtime principal. They do not
6
+ * depend on Node, Express, or NestJS so they can be imported from any surface.
7
+ */
8
+ /** Lifecycle status for an identity user. */
9
+ type IdentityUserStatus = "active" | "disabled" | "locked";
10
+ /** A persisted identity user record. */
11
+ interface IdentityUser {
12
+ userId: string;
13
+ email: string;
14
+ displayName: string | null;
15
+ status: IdentityUserStatus;
16
+ emailVerifiedAt: Date | null;
17
+ /**
18
+ * Whether TOTP-based two-factor authentication is currently active for this account.
19
+ */
20
+ twoFactorEnabled: boolean;
21
+ /**
22
+ * Incremented to invalidate previously issued access/refresh tokens (for example on
23
+ * password change or forced logout). Tokens carry this value and are rejected on mismatch.
24
+ */
25
+ authVersion: number;
26
+ /**
27
+ * Consecutive failed login attempts since the last successful login. Reset to 0 on success.
28
+ * Used by the account lockout feature.
29
+ */
30
+ failedLoginAttempts: number;
31
+ /**
32
+ * When set, the account is temporarily locked until this time. The lockout feature sets
33
+ * this after the configured `maxFailedAttempts` threshold is exceeded.
34
+ */
35
+ lockedUntil: Date | null;
36
+ createdAt: Date;
37
+ updatedAt: Date;
38
+ }
39
+ /** Stored password credential for a user. The plaintext password is never persisted. */
40
+ interface CredentialRecord {
41
+ userId: string;
42
+ /** Opaque, algorithm-tagged password hash. */
43
+ passwordHash: string;
44
+ updatedAt: Date;
45
+ }
46
+ /**
47
+ * A server-side refresh session. The raw refresh token is returned to the client once;
48
+ * only its hash is stored so a database leak does not expose usable tokens.
49
+ */
50
+ interface AuthSession {
51
+ sessionId: string;
52
+ userId: string;
53
+ /** Hash of the current refresh token. Rotated on every refresh. */
54
+ refreshTokenHash: string;
55
+ createdAt: Date;
56
+ expiresAt: Date;
57
+ /** Set when the session has been rotated or revoked; such sessions are unusable. */
58
+ revokedAt: Date | null;
59
+ }
60
+ /** A coarse permission string, e.g. `documents:read`. */
61
+ type Permission = string;
62
+ /** A role groups permissions for assignment to users. */
63
+ interface Role {
64
+ roleId: string;
65
+ name: string;
66
+ description: string | null;
67
+ }
68
+ /** Assignment of a role to a user. */
69
+ interface UserRoleAssignment {
70
+ userId: string;
71
+ roleId: string;
72
+ }
73
+ /** Grant of a permission to a role. */
74
+ interface RolePermissionGrant {
75
+ roleId: string;
76
+ permission: Permission;
77
+ }
78
+ /** Direct grant of a permission to a user, bypassing roles. */
79
+ interface DirectPermissionGrant {
80
+ userId: string;
81
+ permission: Permission;
82
+ }
83
+ /** Names of the supported identity event types for auditing. */
84
+ type IdentityEventType = "user.registered" | "user.login.succeeded" | "user.login.failed" | "user.login.mfa.challenged" | "user.account.locked" | "user.account.unlocked" | "user.email.verification.requested" | "user.email.verified" | "user.password.reset.requested" | "user.password.reset.completed" | "user.2fa.setup.started" | "user.2fa.enabled" | "user.2fa.disabled" | "user.oauth.linked" | "session.refreshed" | "session.revoked" | "authorization.denied";
85
+ /** A linked OAuth / OIDC identity from an external provider (Google, Microsoft, etc.). */
86
+ interface OAuthLinkedAccount {
87
+ userId: string;
88
+ /** Provider identifier, e.g. `"google"` or `"microsoft"`. */
89
+ provider: string;
90
+ /** The user's stable id on the provider side (`sub` claim). */
91
+ providerUserId: string;
92
+ email: string | null;
93
+ displayName: string | null;
94
+ linkedAt: Date;
95
+ }
96
+ /** An audit event emitted by identity flows. */
97
+ interface IdentityEvent {
98
+ type: IdentityEventType;
99
+ userId: string | null;
100
+ /** Free-form, non-sensitive metadata. Never include passwords or raw tokens. */
101
+ metadata: Record<string, string | number | boolean | null>;
102
+ occurredAt: Date;
103
+ }
104
+ /**
105
+ * The authenticated principal hydrated from the store after a token is verified.
106
+ * Attached to the request by the Express middleware / NestJS guard.
107
+ */
108
+ interface AuthenticatedIdentity {
109
+ userId: string;
110
+ email: string;
111
+ displayName: string | null;
112
+ status: IdentityUserStatus;
113
+ emailVerified: boolean;
114
+ roles: readonly string[];
115
+ permissions: readonly Permission[];
116
+ }
117
+ /** A successful authentication result containing tokens and the principal. */
118
+ interface AuthTokens {
119
+ accessToken: string;
120
+ refreshToken: string;
121
+ accessTokenExpiresAt: Date;
122
+ refreshTokenExpiresAt: Date;
123
+ }
124
+ /** Result returned by register/login flows. */
125
+ interface AuthResult {
126
+ user: AuthenticatedIdentity;
127
+ tokens: AuthTokens;
128
+ }
129
+ /**
130
+ * Returned by `login` when the user has 2FA enabled and the TOTP code has not yet
131
+ * been verified. The client must call `verifyMfaChallenge` to complete the login.
132
+ */
133
+ interface MfaRequiredResult {
134
+ kind: "mfa_required";
135
+ /** Short-lived signed token identifying the pending MFA session. */
136
+ mfaToken: string;
137
+ }
138
+ /** Union return type for the login flow — either a full session or an MFA challenge. */
139
+ type LoginResult = AuthResult | MfaRequiredResult;
140
+ /** Token type for email verification or password reset links. */
141
+ type VerificationTokenType = "email_verification" | "password_reset";
142
+ /** A short-lived opaque token stored by hash, used for email verification and password reset. */
143
+ interface VerificationToken {
144
+ /** SHA-256 hash of the raw token (stored; raw token is sent to the user). */
145
+ tokenHash: string;
146
+ userId: string;
147
+ type: VerificationTokenType;
148
+ expiresAt: Date;
149
+ /** Set when the token has been consumed; consumed tokens cannot be reused. */
150
+ usedAt: Date | null;
151
+ }
152
+ /** Persisted TOTP secret for a user. */
153
+ interface TotpSecret {
154
+ userId: string;
155
+ /** Base32-encoded TOTP secret key. */
156
+ secretBase32: string;
157
+ /** Set once the user has confirmed the TOTP code after setup. */
158
+ enabledAt: Date | null;
159
+ createdAt: Date;
160
+ }
161
+ /** Returned by the 2FA setup flow. Display the QR code / secret to the user. */
162
+ interface TotpSetupResult {
163
+ /** Base32-encoded secret to show to the user (or encode as a QR code). */
164
+ secret: string;
165
+ /** OTP Auth URI suitable for QR code display in authenticator apps. */
166
+ otpAuthUri: string;
167
+ }
168
+ /** Verified access-token claims. */
169
+ interface AccessTokenClaims {
170
+ /** Subject — the user id. */
171
+ sub: string;
172
+ /** Auth version the token was minted against. */
173
+ authVersion: number;
174
+ /** Issued-at (seconds since epoch). */
175
+ iat: number;
176
+ /** Expiry (seconds since epoch). */
177
+ exp: number;
178
+ }
179
+ //#endregion
180
+ //#region core/verification-token.d.ts
181
+ /** Input for persisting a new verification token. */
182
+ interface CreateVerificationTokenInput {
183
+ /** SHA-256 hash of the raw token (never store the raw token). */
184
+ tokenHash: string;
185
+ userId: string;
186
+ type: VerificationTokenType;
187
+ expiresAt: Date;
188
+ }
189
+ /**
190
+ * Generates a cryptographically random opaque token and its SHA-256 hash.
191
+ * Returns both: the raw token is sent to the user; only the hash is persisted.
192
+ */
193
+ declare function generateVerificationToken(): {
194
+ token: string;
195
+ tokenHash: string;
196
+ };
197
+ /** Hashes a token presented by the user for secure lookup against stored hashes. */
198
+ declare function hashVerificationToken(token: string): string;
199
+ //#endregion
200
+ //#region core/identity-store.d.ts
201
+ /** Fields required to create a new user (ids/timestamps are assigned by the service). */
202
+ interface CreateIdentityUserInput {
203
+ userId: string;
204
+ email: string;
205
+ displayName: string | null;
206
+ status: IdentityUser["status"];
207
+ authVersion: number;
208
+ createdAt: Date;
209
+ updatedAt: Date;
210
+ }
211
+ /** Fields required to create a new refresh session. */
212
+ interface CreateAuthSessionInput {
213
+ sessionId: string;
214
+ userId: string;
215
+ refreshTokenHash: string;
216
+ createdAt: Date;
217
+ expiresAt: Date;
218
+ }
219
+ /**
220
+ * Storage contract for `@azlib/identity`. Implement this against your own database
221
+ * engine (Postgres, MySQL, SQLite, Prisma, etc.). The package ships predefined schema
222
+ * artifacts under `@azlib/identity/schema/*` you can apply directly.
223
+ *
224
+ * Implementations must treat email lookups as case-insensitive and enforce uniqueness
225
+ * on email. All methods may be async.
226
+ */
227
+ interface IdentityStore {
228
+ findUserByEmail(email: string): Promise<IdentityUser | null>;
229
+ findUserById(userId: string): Promise<IdentityUser | null>;
230
+ createUser(input: CreateIdentityUserInput): Promise<IdentityUser>;
231
+ updateUser(userId: string, patch: Partial<Pick<IdentityUser, "displayName" | "status" | "emailVerifiedAt" | "twoFactorEnabled" | "authVersion" | "failedLoginAttempts" | "lockedUntil">>): Promise<IdentityUser>;
232
+ findCredential(userId: string): Promise<CredentialRecord | null>;
233
+ upsertCredential(record: CredentialRecord): Promise<void>;
234
+ createSession(input: CreateAuthSessionInput): Promise<AuthSession>;
235
+ findSessionById(sessionId: string): Promise<AuthSession | null>;
236
+ /** Marks a session revoked (used during rotation and logout). */
237
+ revokeSession(sessionId: string, revokedAt: Date): Promise<void>;
238
+ /** Replaces the stored refresh-token hash for a session during rotation. */
239
+ rotateSession(sessionId: string, refreshTokenHash: string, expiresAt: Date): Promise<void>;
240
+ /** Revokes every active session for a user (e.g. password change / global logout). */
241
+ revokeAllSessions(userId: string, revokedAt: Date): Promise<void>;
242
+ listRolesForUser(userId: string): Promise<readonly Role[]>;
243
+ listPermissionsForUser(userId: string): Promise<readonly Permission[]>;
244
+ assignRole(assignment: UserRoleAssignment): Promise<void>;
245
+ grantRolePermission(grant: RolePermissionGrant): Promise<void>;
246
+ grantDirectPermission(grant: DirectPermissionGrant): Promise<void>;
247
+ /** Persists a new short-lived verification/reset token (stored as hash). */
248
+ createVerificationToken?(input: CreateVerificationTokenInput): Promise<void>;
249
+ /** Looks up a stored token by its SHA-256 hash. */
250
+ findVerificationToken?(tokenHash: string): Promise<VerificationToken | null>;
251
+ /** Marks a token as consumed so it cannot be reused. */
252
+ markVerificationTokenUsed?(tokenHash: string, usedAt: Date): Promise<void>;
253
+ /** Returns the pending or active TOTP secret for a user, or null if none. */
254
+ findTotpSecret?(userId: string): Promise<TotpSecret | null>;
255
+ /** Creates or replaces the TOTP secret for a user. */
256
+ upsertTotpSecret?(record: TotpSecret): Promise<void>;
257
+ /** Removes the TOTP secret, effectively disabling 2FA at the storage layer. */
258
+ deleteTotpSecret?(userId: string): Promise<void>;
259
+ recordEvent?(event: IdentityEvent): Promise<void>;
260
+ /**
261
+ * Finds the local user linked to a provider + provider user id. Returns null when
262
+ * no OAuth link exists yet.
263
+ */
264
+ findUserByOAuthId?(provider: string, providerUserId: string): Promise<IdentityUser | null>;
265
+ /** Persists a new OAuth link between a local user and their provider identity. */
266
+ createOAuthLink?(link: OAuthLinkedAccount): Promise<void>;
267
+ /** Lists all provider links for a user. */
268
+ listOAuthLinks?(userId: string): Promise<readonly OAuthLinkedAccount[]>;
269
+ }
270
+ //#endregion
271
+ export { RolePermissionGrant as C, VerificationToken as D, UserRoleAssignment as E, VerificationTokenType as O, Role as S, TotpSetupResult as T, IdentityUserStatus as _, generateVerificationToken as a, OAuthLinkedAccount as b, AuthResult as c, AuthenticatedIdentity as d, CredentialRecord as f, IdentityUser as g, IdentityEventType as h, CreateVerificationTokenInput as i, AuthSession as l, IdentityEvent as m, CreateIdentityUserInput as n, hashVerificationToken as o, DirectPermissionGrant as p, IdentityStore as r, AccessTokenClaims as s, CreateAuthSessionInput as t, AuthTokens as u, LoginResult as v, TotpSecret as w, Permission as x, MfaRequiredResult as y };
272
+ //# sourceMappingURL=identity-store-BRRahxcS.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-store-BRRahxcS.d.cts","names":[],"sources":["../core/types.ts","../core/verification-token.ts","../core/identity-store.ts"],"mappings":"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"}