@prismshadow/penguin-server 0.2.15 → 0.2.16
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/api/types.d.ts +86 -40
- package/dist/api/types.js +1 -1
- package/dist/auth-token.d.ts +1 -1
- package/dist/auth-token.js +2 -2
- package/dist/{chunk-NVWAYYRX.js → chunk-3SFJKLQU.js} +38 -3
- package/dist/{chunk-NVWAYYRX.js.map → chunk-3SFJKLQU.js.map} +1 -1
- package/dist/{chunk-5Z4UCHDB.js → chunk-D3JNA6ZI.js} +69 -6
- package/dist/chunk-D3JNA6ZI.js.map +1 -0
- package/dist/{chunk-TOOTEEM4.js → chunk-G7GY7PJU.js} +1 -1
- package/dist/chunk-G7GY7PJU.js.map +1 -0
- package/dist/{chunk-JKJXQTHH.js → chunk-W7JNIJ25.js} +1 -1
- package/dist/chunk-W7JNIJ25.js.map +1 -0
- package/dist/index.js +3413 -2500
- package/dist/index.js.map +1 -1
- package/dist/machine-status.js +1 -1
- package/dist/plugin/index.d.ts +28 -20
- package/dist/reset-admin-password.js +3 -4
- package/dist/reset-admin-password.js.map +1 -1
- package/package.json +5 -9
- package/web-dist/assets/{abnfDiagram-VCTEODGH-CKWh4hoA.js → abnfDiagram-VCTEODGH-0AKFiyig.js} +1 -1
- package/web-dist/assets/{addon-clipboard-DxLqat7q.js → addon-clipboard-BovFnNVg.js} +1 -1
- package/web-dist/assets/{addon-fit-B8oPGPkW.js → addon-fit-B1npgxQk.js} +1 -1
- package/web-dist/assets/{addon-web-links-C0W5TcK0.js → addon-web-links-D88QHj7A.js} +1 -1
- package/web-dist/assets/{arc-Dp9EkaAH.js → arc-Beox1Cgf.js} +1 -1
- package/web-dist/assets/{architectureDiagram-5GKGNRK7-BQ3LUcle.js → architectureDiagram-5GKGNRK7-CC1sLMY1.js} +1 -1
- package/web-dist/assets/{blockDiagram-I7D4REHJ-CZzyU0Jj.js → blockDiagram-I7D4REHJ-B8BY1PkZ.js} +1 -1
- package/web-dist/assets/{c4Diagram-7LVT6UL2-Qps3jeAu.js → c4Diagram-7LVT6UL2-yjY0BkxQ.js} +1 -1
- package/web-dist/assets/channel-mfsAVJLE.js +1 -0
- package/web-dist/assets/{chunk-2Q5K7J3B-CQMntzuX.js → chunk-2Q5K7J3B-DdgIvETg.js} +1 -1
- package/web-dist/assets/{chunk-5VM5RSS4-2H2ZJAte.js → chunk-5VM5RSS4-BE38k1Rs.js} +1 -1
- package/web-dist/assets/{chunk-F27PBJKO-B30xCNBv.js → chunk-F27PBJKO-D4YXmaqQ.js} +1 -1
- package/web-dist/assets/{chunk-IMKFNOWR-Cyfx4zDs.js → chunk-IMKFNOWR-CyJFdThc.js} +1 -1
- package/web-dist/assets/{chunk-JWPE2WC7-DADUytTh.js → chunk-JWPE2WC7-BAM_oEUU.js} +1 -1
- package/web-dist/assets/{chunk-POPQ4Y6H-9bjsAxLS.js → chunk-POPQ4Y6H-BP3D0FVi.js} +1 -1
- package/web-dist/assets/{chunk-SVP7TREG-B9xO1VpN.js → chunk-SVP7TREG-Clk8PdKZ.js} +1 -1
- package/web-dist/assets/{chunk-TICWLB2K-B6oDkrep.js → chunk-TICWLB2K-EvWPnEGg.js} +1 -1
- package/web-dist/assets/{chunk-XXDRQBXY-BbU8DR4B.js → chunk-XXDRQBXY-6p5D0UB1.js} +1 -1
- package/web-dist/assets/classDiagram-ZZMXUADV-BPVO1m8i.js +1 -0
- package/web-dist/assets/classDiagram-v2-VYDZK3BY-BPVO1m8i.js +1 -0
- package/web-dist/assets/{cose-bilkent-JH36ORCC-pkbuyec-.js → cose-bilkent-JH36ORCC-bpkI-tLJ.js} +1 -1
- package/web-dist/assets/{cynefin-OW5HDTMX-DU9YQQnc.js → cynefin-OW5HDTMX-srLaqJ4e.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-5FMLGOSQ-3a3XuhQq.js → cynefinDiagram-5FMLGOSQ-BPfpHSPc.js} +1 -1
- package/web-dist/assets/{dagre-GXQ25YYZ-BfZ9C5CZ.js → dagre-GXQ25YYZ-C4fF5-j7.js} +1 -1
- package/web-dist/assets/{diagram-S7CK7UJ4-BoGhVBMn.js → diagram-S7CK7UJ4-BzBLb_9-.js} +1 -1
- package/web-dist/assets/{diagram-UQ7AKVKN-zE67quty.js → diagram-UQ7AKVKN-BJuJ1o_T.js} +1 -1
- package/web-dist/assets/{diagram-VSXAHHWV-NihoXeXm.js → diagram-VSXAHHWV-DFelN9i9.js} +1 -1
- package/web-dist/assets/{diagram-VX7I27RA-1627np0S.js → diagram-VX7I27RA-BgrEoPyp.js} +1 -1
- package/web-dist/assets/{diagram-Z3DM3KII-Ddg_bUan.js → diagram-Z3DM3KII-C71KiMiX.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-PWID7BFC-CmPUOM4j.js → ebnfDiagram-PWID7BFC-EYteyp1b.js} +1 -1
- package/web-dist/assets/{erDiagram-RLTQ6QDP-DiTnEK72.js → erDiagram-RLTQ6QDP-B6n6-sz6.js} +1 -1
- package/web-dist/assets/{flowDiagram-HODETNUW-mGQ38tRM.js → flowDiagram-HODETNUW-BtoMTdyT.js} +1 -1
- package/web-dist/assets/{ganttDiagram-EL5Y4UJY-DU7MlzpW.js → ganttDiagram-EL5Y4UJY-CbOAa3vS.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-WWUBYQGX-CRE_3vjl.js → gitGraphDiagram-WWUBYQGX-B7-8sszH.js} +1 -1
- package/web-dist/assets/{highlighter-CzfXQ6yd.js → highlighter-Bj5l2XH_.js} +2 -2
- package/web-dist/assets/{highlighter-core-B5CvXcEK.js → highlighter-core-CMXoD8ze.js} +1 -1
- package/web-dist/assets/index-BOCqRT4e.css +1 -0
- package/web-dist/assets/index-BrMpjp2s.js +1286 -0
- package/web-dist/assets/{infoDiagram-27XIBGKW-Cdo6Ar-a.js → infoDiagram-27XIBGKW-BBjf6pkP.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-5VMMS53U-C27pgect.js → ishikawaDiagram-5VMMS53U-BBSvCv45.js} +1 -1
- package/web-dist/assets/{journeyDiagram-3NMN7TZE-CVxtKpLG.js → journeyDiagram-3NMN7TZE-CuHHl5zk.js} +1 -1
- package/web-dist/assets/{kanban-definition-UXKFOSKX-DWA31Da7.js → kanban-definition-UXKFOSKX-DJyP4Myw.js} +1 -1
- package/web-dist/assets/{layout-DWKCU9PO.js → layout-Bqqhdwtt.js} +1 -1
- package/web-dist/assets/{linear-BwCthj_k.js → linear-BZfUSIf8.js} +1 -1
- package/web-dist/assets/{mermaid.core-BcTrmPOv.js → mermaid.core-BlUspEsI.js} +6 -6
- package/web-dist/assets/{mindmap-definition-YA3MSWOX-BLEDhbn1.js → mindmap-definition-YA3MSWOX-BtyMD4wz.js} +1 -1
- package/web-dist/assets/{pegDiagram-XKGWAZYB-CLEM1SDU.js → pegDiagram-XKGWAZYB-BUF_GJ0B.js} +1 -1
- package/web-dist/assets/{pieDiagram-E7YTZNPT-B__g6eF0.js → pieDiagram-E7YTZNPT-nweubbsU.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-AXDQQJYC-C7VQ2LMY.js → quadrantDiagram-AXDQQJYC-B_r4Wkxy.js} +1 -1
- package/web-dist/assets/{railroadDiagram-O6MQD6OU-eWNnzjwS.js → railroadDiagram-O6MQD6OU-Dn7nm0MX.js} +1 -1
- package/web-dist/assets/{requirementDiagram-BXWQKSXE-Bi5qeD4b.js → requirementDiagram-BXWQKSXE-DaagYJ49.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-P5KCCOFB-DG1VOpXX.js → sankeyDiagram-P5KCCOFB-CqEX6H-B.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-WJ2MYXX4-Fhkw73Th.js → sequenceDiagram-WJ2MYXX4-BzLfQO55.js} +1 -1
- package/web-dist/assets/{sizeCapture-INFHLROL-D9E_17SF.js → sizeCapture-INFHLROL-BcUuVH2L.js} +1 -1
- package/web-dist/assets/{stateDiagram-D77RDMKH-Cs5Y0xhW.js → stateDiagram-D77RDMKH-BO3LWLvT.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-MP3YSRHH-B-EuucjM.js +1 -0
- package/web-dist/assets/{swimlanes-42K2YHIH-t-EocvKZ.js → swimlanes-42K2YHIH-etP_hkIB.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-VR7AAH4N-0JbFdDbQ.js +8 -0
- package/web-dist/assets/{timeline-definition-24CTP7MA-CozGCxuA.js → timeline-definition-24CTP7MA-CTLt2XCT.js} +1 -1
- package/web-dist/assets/{vennDiagram-4TSXK5OY-ewU8ycSa.js → vennDiagram-4TSXK5OY-DPO6ZSvH.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-VM6X3IG4-DuAhDu-0.js → wardleyDiagram-VM6X3IG4-DFofGg8b.js} +1 -1
- package/web-dist/assets/{xterm-v5e56GC9.js → xterm-RdyTuaAH.js} +1 -1
- package/web-dist/assets/{xychartDiagram-S5SC5T6Z-BxGuZO23.js → xychartDiagram-S5SC5T6Z-Bgtb34Gu.js} +1 -1
- package/web-dist/index.html +8 -3
- package/web-dist/{workflow-ui.css → workbench-ui.css} +72 -67
- package/dist/benchmark-package.d.ts +0 -39
- package/dist/benchmark-package.js +0 -97
- package/dist/benchmark-package.js.map +0 -1
- package/dist/chunk-54E64LWB.js +0 -63
- package/dist/chunk-54E64LWB.js.map +0 -1
- package/dist/chunk-5Z4UCHDB.js.map +0 -1
- package/dist/chunk-JKJXQTHH.js.map +0 -1
- package/dist/chunk-Q4ON2L6E.js +0 -52
- package/dist/chunk-Q4ON2L6E.js.map +0 -1
- package/dist/chunk-TOOTEEM4.js.map +0 -1
- package/web-dist/assets/channel--PblgLlC.js +0 -1
- package/web-dist/assets/classDiagram-ZZMXUADV-mn8tbuqa.js +0 -1
- package/web-dist/assets/classDiagram-v2-VYDZK3BY-mn8tbuqa.js +0 -1
- package/web-dist/assets/index-BdG4qRyI.js +0 -1275
- package/web-dist/assets/index-W-xYFoIm.css +0 -1
- package/web-dist/assets/stateDiagram-v2-MP3YSRHH-CEM51fAf.js +0 -1
- package/web-dist/assets/swimlanesDiagram-VR7AAH4N-BrR66vrK.js +0 -8
package/dist/chunk-Q4ON2L6E.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
// src/http/errors.ts
|
|
2
|
-
var HttpError = class extends Error {
|
|
3
|
-
constructor(status, code, message, retryAfterSeconds, details) {
|
|
4
|
-
super(message);
|
|
5
|
-
this.status = status;
|
|
6
|
-
this.code = code;
|
|
7
|
-
this.retryAfterSeconds = retryAfterSeconds;
|
|
8
|
-
this.details = details;
|
|
9
|
-
this.name = "HttpError";
|
|
10
|
-
}
|
|
11
|
-
status;
|
|
12
|
-
code;
|
|
13
|
-
retryAfterSeconds;
|
|
14
|
-
details;
|
|
15
|
-
};
|
|
16
|
-
function badRequest(message) {
|
|
17
|
-
return new HttpError(400, "bad_request", message);
|
|
18
|
-
}
|
|
19
|
-
function errorBody(code, message, details) {
|
|
20
|
-
return { error: { code, message, ...details !== void 0 ? { details } : {} } };
|
|
21
|
-
}
|
|
22
|
-
function isMissingCredential(err) {
|
|
23
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
24
|
-
return /missing credentials|api[_ ]?key/i.test(message);
|
|
25
|
-
}
|
|
26
|
-
function modelCredentialMissing(modelId) {
|
|
27
|
-
return new HttpError(
|
|
28
|
-
400,
|
|
29
|
-
"model_credential_missing",
|
|
30
|
-
`Model ${modelId} has no API key yet. Configure it on the Models page first.`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
function handleError(err, c) {
|
|
34
|
-
if (err instanceof HttpError) {
|
|
35
|
-
if (err.retryAfterSeconds !== void 0) {
|
|
36
|
-
c.header("Retry-After", String(err.retryAfterSeconds));
|
|
37
|
-
}
|
|
38
|
-
return c.json(errorBody(err.code, err.message, err.details), err.status);
|
|
39
|
-
}
|
|
40
|
-
console.error(`[server] Unhandled exception: ${err.stack ?? err.message}`);
|
|
41
|
-
return c.json(errorBody("internal", "Internal server error."), 500);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
HttpError,
|
|
46
|
-
badRequest,
|
|
47
|
-
errorBody,
|
|
48
|
-
isMissingCredential,
|
|
49
|
-
modelCredentialMissing,
|
|
50
|
-
handleError
|
|
51
|
-
};
|
|
52
|
-
//# sourceMappingURL=chunk-Q4ON2L6E.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/http/errors.ts"],"sourcesContent":["/**\n * Unified HTTP error: `{error: {code, message, details?}}` response body,\n * with message in English.\n *\n * Routes and services express business errors via throw HttpError; app-level onError\n * uniformly converges these into a JSON response, with unknown errors converged to 500\n * (never leaking internal details to the client).\n *\n * `details` carries the facts a client acts on beside the code — the id a 409 is about, say — so\n * that no client has to parse them out of the message, which is prose and may change.\n */\nimport type { Context } from \"hono\";\nimport type { ErrorBody, ErrorDetails } from \"../api/types.js\";\n\nexport class HttpError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n readonly retryAfterSeconds?: number,\n readonly details?: ErrorDetails,\n ) {\n super(message);\n this.name = \"HttpError\";\n }\n}\n\n/** A 400 for a request the route cannot take as it is; validate.ts re-exports it beside its checks. */\nexport function badRequest(message: string): HttpError {\n return new HttpError(400, \"bad_request\", message);\n}\n\nexport function errorBody(code: string, message: string, details?: ErrorDetails): ErrorBody {\n return { error: { code, message, ...(details !== undefined ? { details } : {}) } };\n}\n\n/**\n * Model missing a credential: the provider SDK throws this at **client-construction\n * time** (hit by both creating a Session and resuming a Session); the original message\n * is full of environment variable names, meaningless to a user — uniformly replaced\n * with a single actionable sentence. The frontend produces localized text by code\n * (message is only a fallback); see web's lib/api-error.ts.\n */\nexport function isMissingCredential(err: unknown): boolean {\n const message = err instanceof Error ? err.message : String(err);\n return /missing credentials|api[_ ]?key/i.test(message);\n}\n\nexport function modelCredentialMissing(modelId: string): HttpError {\n return new HttpError(\n 400,\n \"model_credential_missing\",\n `Model ${modelId} has no API key yet. Configure it on the Models page first.`,\n );\n}\n\n/** app.onError handler: maps HttpError through as-is; everything else is logged and converged to 500. */\nexport function handleError(err: Error, c: Context): Response {\n if (err instanceof HttpError) {\n if (err.retryAfterSeconds !== undefined) {\n c.header(\"Retry-After\", String(err.retryAfterSeconds));\n }\n return c.json(errorBody(err.code, err.message, err.details), err.status as 400);\n }\n // Unknown error: print the stack for diagnosis, but never expose details externally.\n console.error(`[server] Unhandled exception: ${err.stack ?? err.message}`);\n return c.json(errorBody(\"internal\", \"Internal server error.\"), 500);\n}\n"],"mappings":";AAcO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC,YACW,QACA,MACT,SACS,mBACA,SACT;AACA,UAAM,OAAO;AANJ;AACA;AAEA;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EARW;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAKb;AAGO,SAAS,WAAW,SAA4B;AACrD,SAAO,IAAI,UAAU,KAAK,eAAe,OAAO;AAClD;AAEO,SAAS,UAAU,MAAc,SAAiB,SAAmC;AAC1F,SAAO,EAAE,OAAO,EAAE,MAAM,SAAS,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC,EAAG,EAAE;AACnF;AASO,SAAS,oBAAoB,KAAuB;AACzD,QAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,SAAO,mCAAmC,KAAK,OAAO;AACxD;AAEO,SAAS,uBAAuB,SAA4B;AACjE,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA,SAAS,OAAO;AAAA,EAClB;AACF;AAGO,SAAS,YAAY,KAAY,GAAsB;AAC5D,MAAI,eAAe,WAAW;AAC5B,QAAI,IAAI,sBAAsB,QAAW;AACvC,QAAE,OAAO,eAAe,OAAO,IAAI,iBAAiB,CAAC;AAAA,IACvD;AACA,WAAO,EAAE,KAAK,UAAU,IAAI,MAAM,IAAI,SAAS,IAAI,OAAO,GAAG,IAAI,MAAa;AAAA,EAChF;AAEA,UAAQ,MAAM,iCAAiC,IAAI,SAAS,IAAI,OAAO,EAAE;AACzE,SAAO,EAAE,KAAK,UAAU,YAAY,wBAAwB,GAAG,GAAG;AACpE;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/db/repos/users.ts","../src/db/repos/auth-sessions.ts"],"sourcesContent":["/**\n * users table repo: pure SQL wrapper, no business rules.\n * user_id is the login name (a semantic id, specified at creation, immutable).\n */\nimport { Component, Use } from \"@prismshadow/penguin-core/kernel\";\nimport type { Db } from \"../../hmr/capabilities.js\";\nimport type { Users } from \"../../mechanisms/identity.js\";\n\nexport interface UserRow {\n userId: string;\n passwordHash: string;\n isAdmin: boolean;\n /** Still using the initial password (seeded / set by an admin); cleared to 0 once the user changes it. */\n passwordIsInitial: boolean;\n /** Nickname shown in place of the id; null = never set. */\n displayName: string | null;\n /** Avatar as a data URL; null = never set. */\n avatar: string | null;\n createdAt: string;\n}\n\nfunction mapRow(r: Record<string, unknown>): UserRow {\n return {\n userId: r.user_id as string,\n passwordHash: r.password_hash as string,\n isAdmin: (r.is_admin as number) === 1,\n passwordIsInitial: (r.password_is_initial as number) === 1,\n displayName: (r.display_name as string | null) ?? null,\n avatar: (r.avatar as string | null) ?? null,\n createdAt: r.created_at as string,\n };\n}\n\n@Component()\nexport class UsersRepo implements Users {\n @Use() private readonly db!: Db;\n\n insert(row: UserRow): void {\n this.db\n .prepare(\n \"INSERT INTO users (user_id, password_hash, is_admin, password_is_initial, display_name, avatar, created_at)\" +\n \" VALUES (?, ?, ?, ?, ?, ?, ?)\",\n )\n .run(\n row.userId,\n row.passwordHash,\n row.isAdmin ? 1 : 0,\n row.passwordIsInitial ? 1 : 0,\n row.displayName,\n row.avatar,\n row.createdAt,\n );\n }\n\n findById(userId: string): UserRow | null {\n const r = this.db.prepare(\"SELECT * FROM users WHERE user_id = ?\").get(userId);\n return r ? mapRow(r) : null;\n }\n\n /** All users (for the admin user backend), ordered by creation time ascending. */\n list(): UserRow[] {\n const rows = this.db.prepare(\"SELECT * FROM users ORDER BY created_at ASC, user_id ASC\").all();\n return rows.map(mapRow);\n }\n\n count(): number {\n const r = this.db.prepare(\"SELECT COUNT(*) AS n FROM users\").get();\n return (r?.n as number) ?? 0;\n }\n\n /** Update the password hash; isInitial marks whether the password was set by someone else (seed / admin). */\n updatePassword(userId: string, passwordHash: string, isInitial: boolean): void {\n this.db\n .prepare(\"UPDATE users SET password_hash = ?, password_is_initial = ? WHERE user_id = ?\")\n .run(passwordHash, isInitial ? 1 : 0, userId);\n }\n\n /**\n * Writes the profile fields the patch names, leaving the rest as they are: an absent key\n * keeps the stored value, `null` clears it, a string replaces it. A patch naming neither\n * field writes nothing rather than issuing an UPDATE with an empty SET list.\n */\n updateProfile(\n userId: string,\n patch: { displayName?: string | null; avatar?: string | null },\n ): void {\n const sets: string[] = [];\n const values: (string | null)[] = [];\n if (patch.displayName !== undefined) {\n sets.push(\"display_name = ?\");\n values.push(patch.displayName);\n }\n if (patch.avatar !== undefined) {\n sets.push(\"avatar = ?\");\n values.push(patch.avatar);\n }\n if (sets.length === 0) return;\n this.db.prepare(`UPDATE users SET ${sets.join(\", \")} WHERE user_id = ?`).run(...values, userId);\n }\n\n /** Used by admin user deletion and account-creation compensation paths (owned Projects must be cleaned up first). */\n delete(userId: string): void {\n this.db.prepare(\"DELETE FROM users WHERE user_id = ?\").run(userId);\n }\n}\n","/**\n * auth_sessions table repo (server-side sessions backing the HttpOnly cookie). Stores only\n * sha256(token); the raw token appears only in the cookie. `issue()` is the ONE minting point,\n * so a CLI-minted row cannot drift from one the server issues itself.\n */\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { Component, Use } from \"@prismshadow/penguin-core/kernel\";\nimport type { Db } from \"../../hmr/capabilities.js\";\nimport type { AuthSessions } from \"../../mechanisms/identity.js\";\n\n/** How a session was established, as stored. NULL on rows formed before the column existed. */\nexport type SessionViaValue = \"password\" | \"desktop\" | \"setup\" | \"cli\";\n\nexport interface AuthSessionRow {\n tokenHash: string;\n userId: string;\n createdAt: string;\n expiresAt: string;\n via: SessionViaValue | null;\n}\n\n/** sha256 hex of a raw session token — the only form the database ever holds. */\nexport function sessionTokenHash(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n@Component()\nexport class AuthSessionsRepo implements AuthSessions {\n @Use() private readonly db!: Db;\n\n /**\n * Mints a session and returns the raw token for a cookie or the terminal. `maxTtlMs` caps a\n * caller-supplied lifetime (`--ttl-seconds`): one longer than an ordinary session would make\n * a leaked token file outlive every other credential, sliding forever. Expired rows are\n * swept here too, so a cron that only mints does not accumulate them.\n */\n issue(opts: {\n userId: string;\n via: SessionViaValue;\n now: Date;\n ttlMs: number;\n maxTtlMs?: number;\n }): { token: string; expiresAt: string } {\n const ttlMs = Math.max(1_000, Math.min(opts.ttlMs, opts.maxTtlMs ?? opts.ttlMs));\n const token = randomBytes(32).toString(\"base64url\");\n const createdAt = opts.now.toISOString();\n const expiresAt = new Date(opts.now.getTime() + ttlMs).toISOString();\n this.deleteExpired(createdAt);\n this.insert({\n tokenHash: sessionTokenHash(token),\n userId: opts.userId,\n createdAt,\n expiresAt,\n via: opts.via,\n });\n return { token, expiresAt };\n }\n\n insert(row: AuthSessionRow): void {\n this.db\n .prepare(\n \"INSERT INTO auth_sessions (token_hash, user_id, created_at, expires_at, via) VALUES (?, ?, ?, ?, ?)\",\n )\n .run(row.tokenHash, row.userId, row.createdAt, row.expiresAt, row.via);\n }\n\n findByTokenHash(tokenHash: string): AuthSessionRow | null {\n const r = this.db.prepare(\"SELECT * FROM auth_sessions WHERE token_hash = ?\").get(tokenHash);\n if (!r) return null;\n return {\n tokenHash: r.token_hash as string,\n userId: r.user_id as string,\n createdAt: r.created_at as string,\n expiresAt: r.expires_at as string,\n via: (r.via as SessionViaValue | null) ?? null,\n };\n }\n\n /** Sliding renewal: update the expiration time. */\n touch(tokenHash: string, expiresAt: string): void {\n this.db\n .prepare(\"UPDATE auth_sessions SET expires_at = ? WHERE token_hash = ?\")\n .run(expiresAt, tokenHash);\n }\n\n delete(tokenHash: string): void {\n this.db.prepare(\"DELETE FROM auth_sessions WHERE token_hash = ?\").run(tokenHash);\n }\n\n /** Opportunistically clean up expired sessions (called during login/validation). */\n deleteExpired(nowIso: string): void {\n this.db.prepare(\"DELETE FROM auth_sessions WHERE expires_at < ?\").run(nowIso);\n }\n\n /** Clear all sessions for a user (forces re-login after an admin resets the password). */\n deleteByUser(userId: string): void {\n this.db.prepare(\"DELETE FROM auth_sessions WHERE user_id = ?\").run(userId);\n }\n\n /**\n * Clear a user's sessions of one kind. Used to end EVERY first-login session when a password\n * is set: an earlier boot's link may still be live in someone's scrollback, and a `setup`\n * session may change the password without knowing the old one.\n */\n deleteByUserAndVia(userId: string, via: SessionViaValue): void {\n this.db.prepare(\"DELETE FROM auth_sessions WHERE user_id = ? AND via = ?\").run(userId, via);\n }\n}\n"],"mappings":"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","names":["Component","Use","_db_dec","_init","Component","Use"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,C as n}from"./mermaid.core-BcTrmPOv.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-TICWLB2K-B6oDkrep.js";import{_ as i}from"./mermaid.core-BcTrmPOv.js";import"./chunk-5VM5RSS4-2H2ZJAte.js";import"./chunk-XXDRQBXY-BbU8DR4B.js";import"./chunk-POPQ4Y6H-9bjsAxLS.js";import"./chunk-F27PBJKO-B30xCNBv.js";import"./index-BdG4qRyI.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-TICWLB2K-B6oDkrep.js";import{_ as i}from"./mermaid.core-BcTrmPOv.js";import"./chunk-5VM5RSS4-2H2ZJAte.js";import"./chunk-XXDRQBXY-BbU8DR4B.js";import"./chunk-POPQ4Y6H-9bjsAxLS.js";import"./chunk-F27PBJKO-B30xCNBv.js";import"./index-BdG4qRyI.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|