@effect-auth/core 0.1.0-alpha.18 → 0.1.0-alpha.19

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 (118) hide show
  1. package/README.md +4 -5
  2. package/dist/DevEmail.d.ts +44 -0
  3. package/dist/DevEmail.d.ts.map +1 -0
  4. package/dist/DevEmail.js +115 -0
  5. package/dist/DevEmail.js.map +1 -0
  6. package/dist/DevelopmentSeed.d.ts +47 -0
  7. package/dist/DevelopmentSeed.d.ts.map +1 -0
  8. package/dist/DevelopmentSeed.js +337 -0
  9. package/dist/DevelopmentSeed.js.map +1 -0
  10. package/dist/DrizzleBunSqliteStorage.d.ts +1 -1
  11. package/dist/DrizzleBunSqliteStorage.d.ts.map +1 -1
  12. package/dist/DrizzleD1SqliteStorage.d.ts +1 -1
  13. package/dist/DrizzleD1SqliteStorage.d.ts.map +1 -1
  14. package/dist/DrizzleEffectSqliteStorage.d.ts +1 -1
  15. package/dist/DrizzleEffectSqliteStorage.d.ts.map +1 -1
  16. package/dist/DrizzleNodeSqliteStorage.d.ts +1 -1
  17. package/dist/DrizzleNodeSqliteStorage.d.ts.map +1 -1
  18. package/dist/DrizzlePostgresStorage.d.ts +26 -0
  19. package/dist/DrizzlePostgresStorage.d.ts.map +1 -0
  20. package/dist/DrizzlePostgresStorage.js +14 -0
  21. package/dist/DrizzlePostgresStorage.js.map +1 -0
  22. package/dist/EffectQbPostgresStorage.d.ts +8 -1
  23. package/dist/EffectQbPostgresStorage.d.ts.map +1 -1
  24. package/dist/EffectQbPostgresStorage.js +359 -2
  25. package/dist/EffectQbPostgresStorage.js.map +1 -1
  26. package/dist/EffectQbSqliteStorage.d.ts +42 -2
  27. package/dist/EffectQbSqliteStorage.d.ts.map +1 -1
  28. package/dist/EffectQbSqliteStorage.js +337 -1
  29. package/dist/EffectQbSqliteStorage.js.map +1 -1
  30. package/dist/HttpApi/Api.d.ts +151 -98
  31. package/dist/HttpApi/Api.d.ts.map +1 -1
  32. package/dist/HttpApi/Api.js +122 -72
  33. package/dist/HttpApi/Api.js.map +1 -1
  34. package/dist/HttpApi/ClientApi.d.ts +136 -136
  35. package/dist/HttpApi/Endpoints.d.ts +33 -1
  36. package/dist/HttpApi/Endpoints.d.ts.map +1 -1
  37. package/dist/HttpApi/Endpoints.js +31 -2
  38. package/dist/HttpApi/Endpoints.js.map +1 -1
  39. package/dist/HttpApi/Errors.d.ts +11 -3
  40. package/dist/HttpApi/Errors.d.ts.map +1 -1
  41. package/dist/HttpApi/Errors.js +16 -0
  42. package/dist/HttpApi/Errors.js.map +1 -1
  43. package/dist/HttpApi/Middleware.d.ts +12 -0
  44. package/dist/HttpApi/Middleware.d.ts.map +1 -1
  45. package/dist/HttpApi/Middleware.js +8 -0
  46. package/dist/HttpApi/Middleware.js.map +1 -1
  47. package/dist/HttpApi/OAuthDeviceAuthorization.d.ts +106 -0
  48. package/dist/HttpApi/OAuthDeviceAuthorization.d.ts.map +1 -0
  49. package/dist/HttpApi/OAuthDeviceAuthorization.js +415 -0
  50. package/dist/HttpApi/OAuthDeviceAuthorization.js.map +1 -0
  51. package/dist/HttpApi/OAuthToken.d.ts +1 -1
  52. package/dist/HttpApi/OAuthToken.d.ts.map +1 -1
  53. package/dist/HttpApi/OAuthToken.js +1 -1
  54. package/dist/HttpApi/OAuthToken.js.map +1 -1
  55. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts +23 -0
  56. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts.map +1 -0
  57. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js +7 -0
  58. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js.map +1 -0
  59. package/dist/HttpApi/Operations/OAuthToken.d.ts +10 -0
  60. package/dist/HttpApi/Operations/OAuthToken.d.ts.map +1 -1
  61. package/dist/HttpApi/Operations/OAuthToken.js +4 -0
  62. package/dist/HttpApi/Operations/OAuthToken.js.map +1 -1
  63. package/dist/HttpApi/Operations/index.d.ts +1 -0
  64. package/dist/HttpApi/Operations/index.d.ts.map +1 -1
  65. package/dist/HttpApi/Operations/index.js +1 -0
  66. package/dist/HttpApi/Operations/index.js.map +1 -1
  67. package/dist/HttpApi/PasswordContract.d.ts +9 -9
  68. package/dist/HttpApi/Schemas.d.ts +38 -0
  69. package/dist/HttpApi/Schemas.d.ts.map +1 -1
  70. package/dist/HttpApi/Schemas.js +36 -1
  71. package/dist/HttpApi/Schemas.js.map +1 -1
  72. package/dist/HttpApi/index.d.ts +3 -1
  73. package/dist/HttpApi/index.d.ts.map +1 -1
  74. package/dist/HttpApi/index.js +3 -1
  75. package/dist/HttpApi/index.js.map +1 -1
  76. package/dist/OAuth.d.ts +46 -1
  77. package/dist/OAuth.d.ts.map +1 -1
  78. package/dist/OAuth.js +118 -4
  79. package/dist/OAuth.js.map +1 -1
  80. package/dist/OAuthDeviceAuthorization.d.ts +378 -0
  81. package/dist/OAuthDeviceAuthorization.d.ts.map +1 -0
  82. package/dist/OAuthDeviceAuthorization.js +860 -0
  83. package/dist/OAuthDeviceAuthorization.js.map +1 -0
  84. package/dist/OAuthDeviceClient.d.ts +76 -0
  85. package/dist/OAuthDeviceClient.d.ts.map +1 -0
  86. package/dist/OAuthDeviceClient.js +362 -0
  87. package/dist/OAuthDeviceClient.js.map +1 -0
  88. package/dist/PostgresStorageMigrations.d.ts +2 -1
  89. package/dist/PostgresStorageMigrations.d.ts.map +1 -1
  90. package/dist/PostgresStorageMigrations.js +54 -0
  91. package/dist/PostgresStorageMigrations.js.map +1 -1
  92. package/dist/Retention.d.ts +6 -1
  93. package/dist/Retention.d.ts.map +1 -1
  94. package/dist/Retention.js +49 -12
  95. package/dist/Retention.js.map +1 -1
  96. package/dist/SqliteStorageSchemaData.d.ts +2 -0
  97. package/dist/SqliteStorageSchemaData.d.ts.map +1 -0
  98. package/dist/SqliteStorageSchemaData.js +508 -0
  99. package/dist/SqliteStorageSchemaData.js.map +1 -0
  100. package/dist/StorageMigrations.d.ts +2 -1
  101. package/dist/StorageMigrations.d.ts.map +1 -1
  102. package/dist/StorageMigrations.js +32 -0
  103. package/dist/StorageMigrations.js.map +1 -1
  104. package/dist/StorageSchemaGenerator.d.ts +70 -12
  105. package/dist/StorageSchemaGenerator.d.ts.map +1 -1
  106. package/dist/StorageSchemaGenerator.js +478 -82
  107. package/dist/StorageSchemaGenerator.js.map +1 -1
  108. package/migrations/0029_auth_oauth_device_authorization.sql +28 -0
  109. package/migrations/postgres/0010_auth_oauth_device_authorization.sql +50 -0
  110. package/package.json +24 -16
  111. package/dist/DrizzleDurableObjectSqliteStorage.d.ts +0 -19
  112. package/dist/DrizzleDurableObjectSqliteStorage.d.ts.map +0 -1
  113. package/dist/DrizzleDurableObjectSqliteStorage.js +0 -14
  114. package/dist/DrizzleDurableObjectSqliteStorage.js.map +0 -1
  115. package/dist/DrizzleWasmSqliteStorage.d.ts +0 -23
  116. package/dist/DrizzleWasmSqliteStorage.d.ts.map +0 -1
  117. package/dist/DrizzleWasmSqliteStorage.js +0 -15
  118. package/dist/DrizzleWasmSqliteStorage.js.map +0 -1
package/README.md CHANGED
@@ -44,8 +44,6 @@ Storage and runtime adapter subpaths are public alpha adapters. Their names may
44
44
  @effect-auth/core/DrizzleD1SqliteStorage
45
45
  @effect-auth/core/DrizzleBunSqliteStorage
46
46
  @effect-auth/core/DrizzleNodeSqliteStorage
47
- @effect-auth/core/DrizzleDurableObjectSqliteStorage
48
- @effect-auth/core/DrizzleWasmSqliteStorage
49
47
  @effect-auth/core/CloudflareEmail
50
48
  @effect-auth/core/CloudflareRequestMetadata
51
49
  @effect-auth/core/CloudflareRateLimitDurableObject
@@ -53,13 +51,14 @@ Storage and runtime adapter subpaths are public alpha adapters. Their names may
53
51
  @effect-auth/core/AlchemyCloudflareRateLimitDurableObject
54
52
  @effect-auth/core/PasskeySimpleWebAuthn
55
53
  @effect-auth/core/StorageSchemaGenerator
54
+ @effect-auth/core/DevelopmentSeed
56
55
  ```
57
56
 
58
57
  `@effect-auth/core/Testing` is test/dev-only API. Do not wire it into production applications.
59
58
 
60
59
  SQL migrations are packaged as files for copy/read workflows, but the supported TypeScript APIs are `authStorageMigrations` from `@effect-auth/core/StorageMigrations` and `postgresAuthStorageMigrations` from `@effect-auth/core/PostgresStorageMigrations`. Raw SQL files are not importable package subpaths.
61
60
 
62
- For fresh PostgreSQL + Drizzle schema planning, `@effect-auth/core/StorageSchemaGenerator` exposes the same deterministic feature resolver used by the public API at `https://effect-auth.itsbroly.com/api/generator/v1`. Tools and AI agents should call `/catalog`, then `POST /generate` for both `migration-sql` and `drizzle-schema`; they should not infer physical tables from store service types. The packaged runtime Drizzle/PostgreSQL adapter is not available yet.
61
+ For fresh PostgreSQL or SQLite/D1 schema planning, `@effect-auth/core/StorageSchemaGenerator` exposes the same deterministic feature resolver used by the public API at `https://effect-auth.itsbroly.com/api/generator/v1`. Tools and AI agents should call `/catalog`, choose the database and adapter, then request `migration-sql`, `development-seed`, and, for Drizzle, `drizzle-schema`; they should not infer physical tables from store service types. `@effect-auth/core/DevelopmentSeed` provides the fixed 100-user, development-only runtime program used by generated seed launchers. Maintained runtime bridges are available for Drizzle PostgreSQL, D1, Bun SQLite, Node SQLite, and application-provided Effect SQLite databases.
63
62
 
64
63
  Before beta, breaking changes are still allowed when they simplify this API surface. Keep the root metadata-only and add public APIs through explicit subpaths.
65
64
 
@@ -1018,7 +1017,7 @@ import { DrizzleD1SqliteAuthStorageLive } from "@effect-auth/core/DrizzleD1Sqlit
1018
1017
  const StorageLive = DrizzleD1SqliteAuthStorageLive(env.DB);
1019
1018
  ```
1020
1019
 
1021
- Runtime-specific Drizzle SQLite helpers are available for Node, Bun, Cloudflare Durable Object SQLite storage, and WASM/OPFS-style SQLite. They construct the matching Drizzle Effect SQLite database from the Effect SQL client layer, then reuse the same auth storage bridge:
1020
+ Runtime-specific Drizzle SQLite helpers are available for Node and Bun. They construct the matching Drizzle Effect SQLite database from the Effect SQL client layer, then reuse the same auth storage bridge:
1022
1021
 
1023
1022
  ```ts
1024
1023
  import { DrizzleBunSqliteAuthStorageLive } from "@effect-auth/core/DrizzleBunSqliteStorage";
@@ -1028,7 +1027,7 @@ const StorageLive = DrizzleBunSqliteAuthStorageLive({
1028
1027
  });
1029
1028
  ```
1030
1029
 
1031
- Install the matching runtime package when using a runtime-specific subpath, such as `@effect/sql-sqlite-bun`, `@effect/sql-sqlite-node`, `@effect/sql-sqlite-do`, or `@effect/sql-sqlite-wasm`.
1030
+ Install the matching runtime package when using a runtime-specific subpath, such as `@effect/sql-sqlite-bun` or `@effect/sql-sqlite-node`.
1032
1031
 
1033
1032
  Database and ORM packages used only by storage subpaths are optional peers. The metadata-only root does not load them; install the matching optional peers for the adapter subpath your application imports.
1034
1033
 
@@ -0,0 +1,44 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import type { Email, UnixMillis } from "./Identifiers.js";
3
+ import { AuthEmailTemplates, AuthMailer, type AuthEmail, type AuthMailerOptions, type EmailAddress } from "./Mailer.js";
4
+ export type DevEmailKind = AuthEmail["_tag"];
5
+ export interface DevEmailMessage {
6
+ readonly id: string;
7
+ readonly kind: DevEmailKind;
8
+ readonly recipient: Email;
9
+ readonly sender?: EmailAddress;
10
+ readonly subject: string;
11
+ readonly text?: string;
12
+ readonly html?: string;
13
+ readonly headers?: Readonly<Record<string, string>>;
14
+ readonly metadata?: Readonly<Record<string, unknown>>;
15
+ readonly createdAt: UnixMillis;
16
+ readonly expiresAt: UnixMillis;
17
+ }
18
+ export interface DevEmailListOptions {
19
+ readonly recipient?: Email;
20
+ readonly kind?: DevEmailKind;
21
+ readonly limit?: number;
22
+ }
23
+ export type DevEmailStoreOperation = "save" | "list" | "clear";
24
+ declare const DevEmailStoreError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
25
+ readonly _tag: "DevEmailStoreError";
26
+ } & Readonly<A>;
27
+ export declare class DevEmailStoreError extends DevEmailStoreError_base<{
28
+ readonly operation: DevEmailStoreOperation;
29
+ readonly message: string;
30
+ readonly cause?: unknown;
31
+ }> {
32
+ }
33
+ export interface DevEmailStoreService {
34
+ readonly save: (message: DevEmailMessage) => Effect.Effect<void, DevEmailStoreError>;
35
+ readonly list: (options?: DevEmailListOptions) => Effect.Effect<readonly DevEmailMessage[], DevEmailStoreError>;
36
+ readonly clear: () => Effect.Effect<void, DevEmailStoreError>;
37
+ }
38
+ declare const DevEmailStore_base: Context.ServiceClass<DevEmailStore, "auth/DevEmailStore", DevEmailStoreService>;
39
+ export declare class DevEmailStore extends DevEmailStore_base {
40
+ }
41
+ export declare const DevEmailStoreMemoryLive: Layer.Layer<DevEmailStore>;
42
+ export declare const AuthMailerFromDevEmailStoreLive: (options?: AuthMailerOptions) => Layer.Layer<AuthMailer, never, AuthEmailTemplates | DevEmailStore>;
43
+ export {};
44
+ //# sourceMappingURL=DevEmail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevEmail.d.ts","sourceRoot":"","sources":["../src/DevEmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,OAAO,EAAQ,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,kBAAkB,EAClB,UAAU,EAEV,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;;;;AAE/D,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;CAAG;AAEL,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,CACb,OAAO,EAAE,eAAe,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,CACb,OAAO,CAAC,EAAE,mBAAmB,KAC1B,MAAM,CAAC,MAAM,CAAC,SAAS,eAAe,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;CAC/D;;AAED,qBAAa,aAAc,SAAQ,kBAGV;CAAG;AAQ5B,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,CAgD7D,CAAC;AA8CH,eAAO,MAAM,+BAA+B,aACjC,iBAAiB,KACzB,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,kBAAkB,GAAG,aAAa,CAoDjE,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { Clock, Context, Data, Effect, Layer } from "effect";
2
+ import { UnixMillis as makeUnixMillis } from "./Identifiers.js";
3
+ import { AuthEmailTemplates, AuthMailer, AuthMailerError, } from "./Mailer.js";
4
+ export class DevEmailStoreError extends Data.TaggedError("DevEmailStoreError") {
5
+ }
6
+ export class DevEmailStore extends Context.Service()("auth/DevEmailStore") {
7
+ }
8
+ const memoryCapacity = 100;
9
+ const defaultListLimit = 50;
10
+ const cloneMessage = (message) => structuredClone(message);
11
+ export const DevEmailStoreMemoryLive = Layer.sync(DevEmailStore)(() => {
12
+ const messages = new Map();
13
+ return DevEmailStore.of({
14
+ save: (message) => Effect.sync(() => {
15
+ messages.delete(message.id);
16
+ messages.set(message.id, cloneMessage(message));
17
+ while (messages.size > memoryCapacity) {
18
+ const oldestId = messages.keys().next().value;
19
+ if (oldestId === undefined) {
20
+ break;
21
+ }
22
+ messages.delete(oldestId);
23
+ }
24
+ }),
25
+ list: (options = {}) => Effect.sync(() => {
26
+ const limit = Math.max(0, Math.floor(options.limit ?? defaultListLimit));
27
+ const newestFirst = [];
28
+ for (const message of messages.values()) {
29
+ newestFirst.unshift(message);
30
+ }
31
+ return newestFirst
32
+ .filter((message) => (options.recipient === undefined ||
33
+ message.recipient === options.recipient) &&
34
+ (options.kind === undefined || message.kind === options.kind))
35
+ .slice(0, limit)
36
+ .map(cloneMessage);
37
+ }),
38
+ clear: () => Effect.sync(() => {
39
+ messages.clear();
40
+ }),
41
+ });
42
+ });
43
+ const messageId = (input) => {
44
+ switch (input._tag) {
45
+ case "EmailAuth": {
46
+ return input.emailOtp.challengeId;
47
+ }
48
+ case "EmailOtp":
49
+ case "MagicLink":
50
+ case "PasswordReset":
51
+ case "EmailVerification":
52
+ case "LoginApproval": {
53
+ return input.challengeId;
54
+ }
55
+ case "LoginNotification": {
56
+ return (input.reportChallengeId ??
57
+ `${input.sessionId}:${input.occurredAt}:${input.reason}`);
58
+ }
59
+ }
60
+ };
61
+ const messageExpiresAt = (input) => {
62
+ switch (input._tag) {
63
+ case "EmailAuth": {
64
+ return makeUnixMillis(Math.max(Number(input.emailOtp.expiresAt), Number(input.magicLink.expiresAt)));
65
+ }
66
+ case "EmailOtp":
67
+ case "MagicLink":
68
+ case "PasswordReset":
69
+ case "EmailVerification":
70
+ case "LoginApproval": {
71
+ return input.expiresAt;
72
+ }
73
+ case "LoginNotification": {
74
+ return input.reportExpiresAt ?? input.occurredAt;
75
+ }
76
+ }
77
+ };
78
+ export const AuthMailerFromDevEmailStoreLive = (options = {}) => Layer.effect(AuthMailer)(Effect.gen(function* () {
79
+ const store = yield* DevEmailStore;
80
+ const templates = yield* AuthEmailTemplates;
81
+ return AuthMailer.of({
82
+ send: Effect.fn("auth.dev_email.send")(function* (input) {
83
+ yield* Effect.annotateCurrentSpan("auth.email.kind", input._tag);
84
+ const rendered = yield* templates.render(input).pipe(Effect.mapError((cause) => new AuthMailerError({
85
+ message: "Failed to render dev auth email",
86
+ cause,
87
+ })));
88
+ const createdAt = makeUnixMillis(yield* Clock.currentTimeMillis);
89
+ const sender = rendered.from ?? options.from;
90
+ yield* store
91
+ .save({
92
+ id: messageId(input),
93
+ kind: input._tag,
94
+ recipient: input.to,
95
+ ...(sender === undefined ? {} : { sender }),
96
+ subject: rendered.subject,
97
+ ...(rendered.text === undefined ? {} : { text: rendered.text }),
98
+ ...(rendered.html === undefined ? {} : { html: rendered.html }),
99
+ ...(rendered.headers === undefined
100
+ ? {}
101
+ : { headers: rendered.headers }),
102
+ ...(input.metadata === undefined
103
+ ? {}
104
+ : { metadata: input.metadata }),
105
+ createdAt,
106
+ expiresAt: messageExpiresAt(input),
107
+ })
108
+ .pipe(Effect.mapError((cause) => new AuthMailerError({
109
+ message: "Failed to store dev auth email",
110
+ cause,
111
+ })));
112
+ }),
113
+ });
114
+ }));
115
+ //# sourceMappingURL=DevEmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevEmail.js","sourceRoot":"","sources":["../src/DevEmail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { UserId } from "./Identifiers.js";
3
+ import { IdentityKindRegistry } from "./Identity.js";
4
+ import { PasswordHasher } from "./Password.js";
5
+ import { CredentialStore, IdentityStore, RegistrationStore, UserStore } from "./Storage.js";
6
+ export declare const developmentSeedUserCount: 100;
7
+ export declare const developmentSeedPassword: "password";
8
+ export declare const developmentSeedVersion: 1;
9
+ export type DevelopmentSeedUserState = "active-verified" | "unverified" | "disabled" | "revoked-identity" | "revoked-password";
10
+ export interface DevelopmentSeedUserDefinition {
11
+ readonly userNumber: number;
12
+ readonly email: string;
13
+ readonly state: DevelopmentSeedUserState;
14
+ }
15
+ export interface SeedDevelopmentUserResult extends DevelopmentSeedUserDefinition {
16
+ readonly userId: UserId;
17
+ readonly outcome: "created" | "existing";
18
+ }
19
+ export interface SeedDevelopmentUsersResult {
20
+ readonly created: number;
21
+ readonly existing: number;
22
+ readonly users: readonly SeedDevelopmentUserResult[];
23
+ }
24
+ export interface DevelopmentSeedService {
25
+ readonly seedUsers: Effect.Effect<SeedDevelopmentUsersResult, DevelopmentSeedError>;
26
+ readonly seedPasswordUsers: Effect.Effect<SeedDevelopmentUsersResult, DevelopmentSeedError, CredentialStore | PasswordHasher>;
27
+ }
28
+ export type DevelopmentSeedErrorReason = "normalization" | "password-hash" | "storage" | "registration" | "ownership" | "state";
29
+ declare const DevelopmentSeedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
30
+ readonly _tag: "DevelopmentSeedError";
31
+ } & Readonly<A>;
32
+ export declare class DevelopmentSeedError extends DevelopmentSeedError_base<{
33
+ readonly reason: DevelopmentSeedErrorReason;
34
+ readonly message: string;
35
+ readonly userNumber?: number;
36
+ readonly cause?: unknown;
37
+ }> {
38
+ }
39
+ export declare const developmentSeedUsers: readonly DevelopmentSeedUserDefinition[];
40
+ declare const DevelopmentSeed_base: Context.ServiceClass<DevelopmentSeed, "auth/DevelopmentSeed", DevelopmentSeedService> & {
41
+ readonly make: Effect.Effect<DevelopmentSeedService, never, IdentityKindRegistry | IdentityStore | RegistrationStore | UserStore>;
42
+ };
43
+ export declare class DevelopmentSeed extends DevelopmentSeed_base {
44
+ }
45
+ export declare const DevelopmentSeedLive: Layer.Layer<DevelopmentSeed, never, IdentityKindRegistry | IdentityStore | RegistrationStore | UserStore>;
46
+ export {};
47
+ //# sourceMappingURL=DevelopmentSeed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevelopmentSeed.d.ts","sourceRoot":"","sources":["../src/DevelopmentSeed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,OAAO,EAAQ,MAAM,EAAE,KAAK,EAAoB,MAAM,QAAQ,CAAC;AAE/E,OAAO,EAAwC,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAsB,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,SAAS,EACV,MAAM,cAAc,CAAC;AAOtB,eAAO,MAAM,wBAAwB,EAAG,GAAY,CAAC;AACrD,eAAO,MAAM,uBAAuB,EAAG,UAAmB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,EAAG,CAAU,CAAC;AAKjD,MAAM,MAAM,wBAAwB,GAChC,iBAAiB,GACjB,YAAY,GACZ,UAAU,GACV,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,wBAAwB,CAAC;CAC1C;AAED,MAAM,WAAW,yBAA0B,SAAQ,6BAA6B;IAC9E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,UAAU,CAAC;CAC1C;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAC/B,0BAA0B,EAC1B,oBAAoB,CACrB,CAAC;IACF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CACvC,0BAA0B,EAC1B,oBAAoB,EACpB,eAAe,GAAG,cAAc,CACjC,CAAC;CACH;AAED,MAAM,MAAM,0BAA0B,GAClC,eAAe,GACf,eAAe,GACf,SAAS,GACT,cAAc,GACd,WAAW,GACX,OAAO,CAAC;;;;AAEZ,qBAAa,oBAAqB,SAAQ,0BAExC;IACA,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;CAAG;AAiCL,eAAO,MAAM,oBAAoB,EAAE,SAAS,6BAA6B,EAUtE,CAAC;;;;AA4NJ,qBAAa,eAAgB,SAAQ,oBAsWnC;CAAG;AAEL,eAAO,MAAM,mBAAmB,2GAE/B,CAAC"}
@@ -0,0 +1,337 @@
1
+ import { Clock, Context, Data, Effect, Layer, Option, Redacted } from "effect";
2
+ import { CredentialId, IdentityId, UnixMillis, UserId } from "./Identifiers.js";
3
+ import { emailLoginIdentity, IdentityKindRegistry } from "./Identity.js";
4
+ import { PasswordHasher } from "./Password.js";
5
+ import { CredentialStore, IdentityStore, RegistrationStore, UserStore, } from "./Storage.js";
6
+ export const developmentSeedUserCount = 100;
7
+ export const developmentSeedPassword = "password";
8
+ export const developmentSeedVersion = 1;
9
+ const developmentSeedOwner = "@effect-auth/core/DevelopmentSeed";
10
+ const developmentSeedMetadataKey = "effectAuthDevelopmentSeed";
11
+ export class DevelopmentSeedError extends Data.TaggedError("DevelopmentSeedError") {
12
+ }
13
+ const knownStates = [
14
+ "active-verified",
15
+ "unverified",
16
+ "disabled",
17
+ "revoked-identity",
18
+ "revoked-password",
19
+ ];
20
+ const shuffledRemainingStates = () => {
21
+ const states = [
22
+ ...Array.from({ length: 84 }).fill("active-verified"),
23
+ ...Array.from({ length: 7 }).fill("unverified"),
24
+ ...Array.from({ length: 3 }).fill("disabled"),
25
+ "revoked-identity",
26
+ ];
27
+ let randomState = 0x45_ff_ec_7a;
28
+ for (let index = states.length - 1; index > 0; index -= 1) {
29
+ randomState = Math.imul(randomState, 1_664_525) + 1_013_904_223;
30
+ if (randomState < 0) {
31
+ randomState += 4_294_967_296;
32
+ }
33
+ const swapIndex = randomState % (index + 1);
34
+ [states[index], states[swapIndex]] = [states[swapIndex], states[index]];
35
+ }
36
+ return states;
37
+ };
38
+ export const developmentSeedUsers = Object.freeze([...knownStates, ...shuffledRemainingStates()].map((state, index) => {
39
+ const userNumber = index + 1;
40
+ return Object.freeze({
41
+ userNumber,
42
+ email: `user${userNumber}@example.test`,
43
+ state,
44
+ });
45
+ }));
46
+ const userIdFor = (userNumber) => UserId(`effect-auth-development-user-${userNumber}`);
47
+ const identityIdFor = (userNumber) => IdentityId(`effect-auth-development-email-${userNumber}`);
48
+ const credentialIdFor = (userNumber) => CredentialId(`effect-auth-development-password-${userNumber}`);
49
+ const metadataFor = (definition) => ({
50
+ [developmentSeedMetadataKey]: {
51
+ owner: developmentSeedOwner,
52
+ version: developmentSeedVersion,
53
+ userNumber: definition.userNumber,
54
+ state: definition.state,
55
+ },
56
+ });
57
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
58
+ const hasSeedOwnership = (metadata, definition) => {
59
+ const marker = metadata?.[developmentSeedMetadataKey];
60
+ return (isRecord(marker) &&
61
+ marker.owner === developmentSeedOwner &&
62
+ marker.version === developmentSeedVersion &&
63
+ marker.userNumber === definition.userNumber &&
64
+ marker.state === definition.state);
65
+ };
66
+ const failure = (definition, reason, message, cause) => new DevelopmentSeedError({
67
+ reason,
68
+ message,
69
+ userNumber: definition.userNumber,
70
+ ...(cause === undefined ? {} : { cause }),
71
+ });
72
+ const readExistingRows = (definition, users, identities, credentials) => {
73
+ const userId = userIdFor(definition.userNumber);
74
+ return Effect.all({
75
+ user: users.findById(userId),
76
+ identity: identities.findById(identityIdFor(definition.userNumber)),
77
+ credential: credentials === undefined
78
+ ? Effect.succeed(Option.none())
79
+ : credentials.findPasswordByUserId(userId),
80
+ }).pipe(Effect.mapError((cause) => failure(definition, "storage", `Failed to read development seed user ${definition.userNumber}.`, cause)));
81
+ };
82
+ const effectiveState = (definition, includePassword) => definition.state === "revoked-password" && !includePassword
83
+ ? "active-verified"
84
+ : definition.state;
85
+ const validateExistingRows = (definition, rows, includePassword, normalizedValue, allowPendingIdentityRevocation = false) =>
86
+ // oxlint-disable-next-line eslint/complexity -- validation compares the owned aggregate's identity and lifecycle state before accepting a rerun
87
+ Effect.gen(function* () {
88
+ if (Option.isNone(rows.user) ||
89
+ Option.isNone(rows.identity) ||
90
+ (includePassword && Option.isNone(rows.credential)) ||
91
+ (!includePassword && Option.isSome(rows.credential))) {
92
+ return yield* failure(definition, "state", `Development seed user ${definition.userNumber} is only partially present.`);
93
+ }
94
+ const user = rows.user.value;
95
+ const identity = rows.identity.value;
96
+ const credential = Option.getOrUndefined(rows.credential);
97
+ if (!hasSeedOwnership(user.metadata, definition) ||
98
+ !hasSeedOwnership(identity.metadata, definition) ||
99
+ (credential !== undefined &&
100
+ !hasSeedOwnership(credential.metadata, definition))) {
101
+ return yield* failure(definition, "ownership", `Development seed user ${definition.userNumber} conflicts with data not owned by this seed version.`);
102
+ }
103
+ const state = effectiveState(definition, includePassword);
104
+ const expectsDisabled = state === "disabled";
105
+ const expectsVerified = state !== "unverified" && state !== "revoked-identity";
106
+ const expectsRevokedIdentity = state === "revoked-identity";
107
+ const expectsRevokedPassword = state === "revoked-password";
108
+ const identityRevoked = identity.revokedAt !== undefined;
109
+ const revocationMatches = identityRevoked === expectsRevokedIdentity ||
110
+ (allowPendingIdentityRevocation &&
111
+ expectsRevokedIdentity &&
112
+ !identityRevoked);
113
+ if (user.id !== userIdFor(definition.userNumber) ||
114
+ (user.disabledAt !== undefined) !== expectsDisabled ||
115
+ identity.id !== identityIdFor(definition.userNumber) ||
116
+ identity.userId !== user.id ||
117
+ identity.scope.type !== "global" ||
118
+ identity.kind !== "email" ||
119
+ identity.value !== definition.email ||
120
+ identity.normalizedValue !== normalizedValue ||
121
+ (identity.verifiedAt !== undefined) !== expectsVerified ||
122
+ !revocationMatches ||
123
+ identity.isPrimaryLogin === expectsRevokedIdentity ||
124
+ (credential !== undefined &&
125
+ (credential.id !== credentialIdFor(definition.userNumber) ||
126
+ credential.userId !== user.id ||
127
+ (credential.revokedAt !== undefined) !== expectsRevokedPassword))) {
128
+ return yield* failure(definition, "state", `Development seed user ${definition.userNumber} does not match its expected state.`);
129
+ }
130
+ });
131
+ const registrationInputFor = (definition, includePassword, normalized, now, passwordHash) => {
132
+ const state = effectiveState(definition, includePassword);
133
+ const userId = userIdFor(definition.userNumber);
134
+ const metadata = metadataFor(definition);
135
+ return {
136
+ user: {
137
+ id: userId,
138
+ createdAt: now,
139
+ updatedAt: now,
140
+ ...(state === "disabled" ? { disabledAt: now } : {}),
141
+ metadata,
142
+ },
143
+ identity: {
144
+ id: identityIdFor(definition.userNumber),
145
+ userId,
146
+ scope: normalized.scope,
147
+ kind: normalized.kind,
148
+ value: normalized.value,
149
+ normalizedValue: normalized.normalizedValue,
150
+ ...(state === "unverified" || state === "revoked-identity"
151
+ ? {}
152
+ : { verifiedAt: now }),
153
+ isPrimaryLogin: state !== "revoked-identity",
154
+ createdAt: now,
155
+ metadata,
156
+ },
157
+ ...(includePassword && passwordHash !== undefined
158
+ ? {
159
+ passwordCredential: {
160
+ id: credentialIdFor(definition.userNumber),
161
+ userId,
162
+ passwordHash,
163
+ createdAt: now,
164
+ updatedAt: now,
165
+ ...(state === "revoked-password" ? { revokedAt: now } : {}),
166
+ metadata,
167
+ },
168
+ }
169
+ : {}),
170
+ };
171
+ };
172
+ export class DevelopmentSeed extends Context.Service()("auth/DevelopmentSeed", {
173
+ make: Effect.gen(function* () {
174
+ const users = yield* UserStore;
175
+ const identities = yield* IdentityStore;
176
+ const registration = yield* RegistrationStore;
177
+ const identityKinds = yield* IdentityKindRegistry;
178
+ const runSeed = (password) => Effect.gen(function* () {
179
+ const includePassword = password !== undefined;
180
+ const now = UnixMillis(yield* Clock.currentTimeMillis);
181
+ let passwordHash;
182
+ const verifiedPasswordHashes = new Set();
183
+ const getPasswordHash = () => {
184
+ if (passwordHash !== undefined) {
185
+ return Effect.succeed(passwordHash);
186
+ }
187
+ if (password === undefined) {
188
+ return Effect.fail(new DevelopmentSeedError({
189
+ reason: "password-hash",
190
+ message: "Password seed dependencies are unavailable.",
191
+ }));
192
+ }
193
+ return password.hasher
194
+ .hash({ password: Redacted.make(developmentSeedPassword) })
195
+ .pipe(Effect.map((hash) => {
196
+ passwordHash = hash;
197
+ return hash;
198
+ }), Effect.mapError((cause) => new DevelopmentSeedError({
199
+ reason: "password-hash",
200
+ message: "Failed to hash the development seed password.",
201
+ cause,
202
+ })));
203
+ };
204
+ const validatePasswordHash = (definition, credential) => {
205
+ const { passwordHash: storedHash } = credential;
206
+ if (verifiedPasswordHashes.has(storedHash)) {
207
+ return Effect.void;
208
+ }
209
+ if (password === undefined) {
210
+ return Effect.fail(failure(definition, "password-hash", "Password seed dependencies are unavailable."));
211
+ }
212
+ return password.hasher
213
+ .verify({
214
+ hash: storedHash,
215
+ password: Redacted.make(developmentSeedPassword),
216
+ })
217
+ .pipe(Effect.mapError((cause) => failure(definition, "password-hash", `Failed to verify the password for development seed user ${definition.userNumber}.`, cause)), Effect.flatMap((valid) => valid
218
+ ? Effect.sync(() => {
219
+ verifiedPasswordHashes.add(storedHash);
220
+ passwordHash ??= storedHash;
221
+ })
222
+ : Effect.fail(failure(definition, "state", `Development seed user ${definition.userNumber} no longer uses the documented password.`))));
223
+ };
224
+ const acceptExistingRows = (definition, normalizedValue, rows) => Effect.gen(function* () {
225
+ let validatedRows = rows;
226
+ if (effectiveState(definition, includePassword) ===
227
+ "revoked-identity" &&
228
+ Option.isSome(rows.identity) &&
229
+ rows.identity.value.revokedAt === undefined) {
230
+ yield* validateExistingRows(definition, rows, includePassword, normalizedValue, true);
231
+ yield* identities
232
+ .revoke({
233
+ id: rows.identity.value.id,
234
+ userId: userIdFor(definition.userNumber),
235
+ expectedUpdatedAt: rows.identity.value.updatedAt,
236
+ revokedAt: now,
237
+ reason: "development-seed",
238
+ })
239
+ .pipe(Effect.mapError((cause) => failure(definition, "storage", `Failed to finish revoking ${definition.email}.`, cause)));
240
+ validatedRows = yield* readExistingRows(definition, users, identities, password?.credentials);
241
+ }
242
+ yield* validateExistingRows(definition, validatedRows, includePassword, normalizedValue);
243
+ if (includePassword && Option.isSome(validatedRows.credential)) {
244
+ yield* validatePasswordHash(definition, validatedRows.credential.value);
245
+ }
246
+ return {
247
+ ...definition,
248
+ state: effectiveState(definition, includePassword),
249
+ userId: userIdFor(definition.userNumber),
250
+ outcome: "existing",
251
+ };
252
+ });
253
+ const hasCompleteRows = (rows) => Option.isSome(rows.user) &&
254
+ Option.isSome(rows.identity) &&
255
+ (includePassword
256
+ ? Option.isSome(rows.credential)
257
+ : Option.isNone(rows.credential));
258
+ const results = [];
259
+ for (const definition of developmentSeedUsers) {
260
+ const normalized = yield* identityKinds
261
+ .normalize(emailLoginIdentity(definition.email))
262
+ .pipe(Effect.mapError((cause) => failure(definition, "normalization", `Failed to normalize ${definition.email}.`, cause)));
263
+ const existingRows = yield* readExistingRows(definition, users, identities, password?.credentials);
264
+ const allAbsent = Option.isNone(existingRows.user) &&
265
+ Option.isNone(existingRows.identity) &&
266
+ Option.isNone(existingRows.credential);
267
+ if (!allAbsent) {
268
+ const existingResult = yield* acceptExistingRows(definition, normalized.normalizedValue, existingRows);
269
+ results.push(existingResult);
270
+ continue;
271
+ }
272
+ const activeIdentity = yield* identities
273
+ .findByKindAndNormalizedValue(normalized)
274
+ .pipe(Effect.mapError((cause) => failure(definition, "storage", `Failed to check ${definition.email} for conflicts.`, cause)));
275
+ if (Option.isSome(activeIdentity)) {
276
+ const racedRows = yield* readExistingRows(definition, users, identities, password?.credentials);
277
+ if (hasCompleteRows(racedRows)) {
278
+ const racedResult = yield* acceptExistingRows(definition, normalized.normalizedValue, racedRows);
279
+ results.push(racedResult);
280
+ continue;
281
+ }
282
+ return yield* failure(definition, "ownership", `${definition.email} is already owned by another user.`);
283
+ }
284
+ const hash = includePassword ? yield* getPasswordHash() : undefined;
285
+ const registrationResult = yield* registration
286
+ .create(registrationInputFor(definition, includePassword, normalized, now, hash))
287
+ .pipe(Effect.map((registered) => ({ _tag: "Created", registered })), Effect.catch((error) => readExistingRows(definition, users, identities, password?.credentials).pipe(Effect.flatMap((rows) => hasCompleteRows(rows)
288
+ ? acceptExistingRows(definition, normalized.normalizedValue, rows).pipe(Effect.map((result) => ({ _tag: "Existing", result })))
289
+ : Effect.fail(failure(definition, "registration", `Failed to create development seed user ${definition.userNumber}.`, error))))));
290
+ if (registrationResult._tag === "Existing") {
291
+ results.push(registrationResult.result);
292
+ continue;
293
+ }
294
+ const { registered } = registrationResult;
295
+ if (effectiveState(definition, includePassword) === "revoked-identity") {
296
+ const revoked = yield* identities
297
+ .revoke({
298
+ id: registered.identity.id,
299
+ userId: registered.user.id,
300
+ expectedUpdatedAt: registered.identity.updatedAt,
301
+ revokedAt: now,
302
+ reason: "development-seed",
303
+ })
304
+ .pipe(Effect.mapError((cause) => failure(definition, "storage", `Failed to revoke ${definition.email}.`, cause)));
305
+ if (Option.isNone(revoked)) {
306
+ const rows = yield* readExistingRows(definition, users, identities, password?.credentials);
307
+ yield* validateExistingRows(definition, rows, includePassword, normalized.normalizedValue);
308
+ }
309
+ }
310
+ results.push({
311
+ ...definition,
312
+ state: effectiveState(definition, includePassword),
313
+ userId: registered.user.id,
314
+ outcome: "created",
315
+ });
316
+ }
317
+ return {
318
+ created: results.filter(({ outcome }) => outcome === "created")
319
+ .length,
320
+ existing: results.filter(({ outcome }) => outcome === "existing")
321
+ .length,
322
+ users: results,
323
+ };
324
+ });
325
+ return {
326
+ seedUsers: runSeed().pipe(Effect.withSpan("auth.development_seed.seed_users")),
327
+ seedPasswordUsers: Effect.gen(function* () {
328
+ const credentials = yield* CredentialStore;
329
+ const hasher = yield* PasswordHasher;
330
+ return yield* runSeed({ credentials, hasher });
331
+ }).pipe(Effect.withSpan("auth.development_seed.seed_password_users")),
332
+ };
333
+ }),
334
+ }) {
335
+ }
336
+ export const DevelopmentSeedLive = Layer.effect(DevelopmentSeed)(DevelopmentSeed.make);
337
+ //# sourceMappingURL=DevelopmentSeed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevelopmentSeed.js","sourceRoot":"","sources":["../src/DevelopmentSeed.ts"],"names":[],"mappings":"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"}