@storyshelf/core 0.6.0 → 0.6.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/auth.d.mts CHANGED
@@ -89,6 +89,13 @@ interface Auth {
89
89
  /** Revoke one session by token (accepts the signed cookie value). */
90
90
  destroySession: (sessionToken: string) => Promise<void>;
91
91
  }
92
+ /** Minimum password length for local accounts (matches legacy policy). */
93
+ declare const MIN_PASSWORD_LENGTH = 12;
94
+ /**
95
+ * Raw session token from a possibly-signed cookie value (`token.signature`).
96
+ * Single shared parser: cookies, CSRF binding, and table lookups must agree.
97
+ */
98
+ declare function unsignedToken(value: string): string;
92
99
  //#endregion
93
- export { Auth, EngineLoginMethod, EngineLoginMethodKind, EnginePasskeyInfo, EngineSessionInfo };
100
+ export { Auth, EngineLoginMethod, EngineLoginMethodKind, EnginePasskeyInfo, EngineSessionInfo, MIN_PASSWORD_LENGTH, unsignedToken };
94
101
  //# sourceMappingURL=auth.d.mts.map
package/dist/auth.mjs CHANGED
@@ -1,4 +1,17 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- export {};
4
+ //#region src/auth.ts
5
+ /** Minimum password length for local accounts (matches legacy policy). */
6
+ const MIN_PASSWORD_LENGTH = 12;
7
+ /**
8
+ * Raw session token from a possibly-signed cookie value (`token.signature`).
9
+ * Single shared parser: cookies, CSRF binding, and table lookups must agree.
10
+ */
11
+ function unsignedToken(value) {
12
+ return value.split(".")[0] ?? "";
13
+ }
14
+ //#endregion
15
+ export { MIN_PASSWORD_LENGTH, unsignedToken };
16
+
17
+ //# sourceMappingURL=auth.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.mjs","names":[],"sources":["../src/auth.ts"],"sourcesContent":["/**\n * Auth singleton surface: the shelf authentication contract (not an adapter).\n *\n * Owned by core so `ShelfOptions.auth` needs no dependency edge into the\n * engine package (which would cycle: the engine already depends on core).\n * `@storyshelf/auth` implements this interface and re-exports it; app code\n * imports `Auth` (and the shared runtime helpers below) from\n * `@storyshelf/core/auth`, so a server without auth never needs the engine.\n */\nimport type { AuthUser } from \"./types.ts\";\n\n/** Login widget kinds in display order (the shelf plugin contract). */\nexport type EngineLoginMethodKind = \"password\" | \"oauth\" | \"passkey\" | \"sso\";\n\n/**\n * One login widget on the descriptor-driven login page.\n *\n * Plugin contract: `password` posts the credential form to\n * `/auth/engine/login`; `oauth`/`sso` link at `/auth/engine/:id` (the app\n * starts the provider flow server-side); `passkey` is JS-driven on the page\n * (its `url` is an unused fallback). Method ids must be unique across all\n * providers (checked at boot).\n */\nexport interface EngineLoginMethod {\n kind: EngineLoginMethodKind;\n id: string;\n label: string;\n}\n\n/** One device session for the profile device list. */\nexport interface EngineSessionInfo {\n id: string;\n token: string;\n ipAddress: string | null;\n userAgent: string | null;\n createdAt: string;\n expiresAt: string;\n}\n\n/** One registered passkey for the profile page. */\nexport interface EnginePasskeyInfo {\n id: string;\n name: string | null;\n deviceType: string;\n backedUp: boolean;\n transports: string | null;\n aaguid: string | null;\n createdAt: string;\n}\n\n/** Auth singleton: the shelf authentication surface (not an adapter). */\nexport interface Auth {\n /** Raw engine handler (mount at `/api/auth/*`). */\n handler: (request: Request) => Response | Promise<Response>;\n /** Login methods in display order (drives the login page). */\n loginMethods: () => EngineLoginMethod[];\n /** One-shot boot validation (secret strength); the app calls it directly. */\n setup: () => Promise<void>;\n /** Stage a shelf user and mint a single-use invite token. */\n issueInvite: (input: {\n email: string;\n name: string;\n role: AuthUser[\"role\"];\n }) => Promise<{ inviteId: string; token: string; expiresAt: string }>;\n /** Check an invite token without consuming it (drives the accept page). */\n verifyInvite: (input: { inviteId: string; token: string }) => Promise<{\n email: string;\n name: string;\n }>;\n /** Consume an invite: set the engine credential and return the shelf user. */\n acceptInvite: (input: { inviteId: string; token: string; password: string }) => Promise<AuthUser>;\n /** Whether WebAuthn passkeys are enabled (drives the profile section). */\n passkeysEnabled: () => boolean;\n /** Active device sessions for the profile page (newest first). */\n listSessions: (userId: string) => Promise<EngineSessionInfo[]>;\n /** Registered passkeys for the profile page (oldest first). */\n listPasskeys: (userId: string) => Promise<EnginePasskeyInfo[]>;\n /** Whether the user has a local credential (shows the password form). */\n hasPassword: (userId: string) => Promise<boolean>;\n /**\n * Disable or re-enable a user: flips the shelf flag and eagerly revokes\n * every engine session (the per-request check is the backstop).\n */\n setDisabled: (userId: string, disabled: boolean) => Promise<void>;\n /** Resolve the session user from a request (null when anonymous). */\n check: (request: Request) => Promise<AuthUser | null>;\n /** Forbidden by design: sessions mint at engine endpoints, never here. */\n createSession: (user: AuthUser) => Promise<string>;\n /** Revoke one session by token (accepts the signed cookie value). */\n destroySession: (sessionToken: string) => Promise<void>;\n}\n\n/** Minimum password length for local accounts (matches legacy policy). */\nexport const MIN_PASSWORD_LENGTH = 12;\n\n/**\n * Raw session token from a possibly-signed cookie value (`token.signature`).\n * Single shared parser: cookies, CSRF binding, and table lookups must agree.\n */\nexport function unsignedToken(value: string): string {\n return value.split(\".\")[0] ?? \"\";\n}\n"],"mappings":";;;;;AA6FA,MAAa,sBAAsB;;;;;AAMnC,SAAgB,cAAc,OAAuB;CACnD,OAAO,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM;AAChC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storyshelf/core",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "StoryShelf core: adapter interfaces, models, capture pipeline, diff, and retention (no HTTP).",
5
5
  "keywords": [
6
6
  "chromatic-alternative",
@@ -27,6 +27,9 @@
27
27
  "dist"
28
28
  ],
29
29
  "type": "module",
30
+ "engines": {
31
+ "node": ">=24"
32
+ },
30
33
  "sideEffects": false,
31
34
  "types": "./dist/index.d.mts",
32
35
  "exports": {
@@ -196,7 +199,7 @@
196
199
  },
197
200
  "dependencies": {
198
201
  "@opentelemetry/api": "^1.9.0",
199
- "@storyshelf/affected": "0.6.0",
202
+ "@storyshelf/affected": "0.6.2",
200
203
  "drizzle-orm": "^0.44.0",
201
204
  "pino": "^10.3.1",
202
205
  "pixelmatch": "^7.1.0",