better-dsh 0.2.4-c → 0.2.5-a
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/cordis.patch.yml +11 -0
- package/docs/50_test-reports/2026-09-28-ctx-scheme/351/225/277/344/274/232/350/257/235utility/345/256/236/346/265/213/346/212/245/345/221/212.md +155 -0
- package/docs/50_test-reports/2026-10-01-v0.2.4d-web-password-gate/345/256/236/346/265/213/346/212/245/345/221/212.md +105 -0
- package/docs/50_test-reports/2026-10-02-ctx-navigation/345/256/236/346/265/213/346/212/245/345/221/212.md +137 -0
- package/docs/50_test-reports/2026-10-02-v0.2.0-rc.2/345/257/271/351/275/220/350/275/256/345/256/236/346/265/213/346/212/245/345/221/212.md +38 -0
- package/docs/specs/ctx/spec.md +78 -6
- package/docs/specs/model-picker-ios-blur/spec.md +168 -0
- package/docs/superpowers/plans/2026-10-02-ctx-navigation.md +319 -0
- package/docs/superpowers/specs/2026-10-02-ctx-navigation-design.md +209 -0
- package/lib/fs-aware/sandbox-plugin.js +2 -2
- package/lib/url-schemes/index.js +194 -37
- package/lib/web-password.d.ts +156 -0
- package/lib/web-password.js +562 -0
- package/lib/{wrap-Dr8XtIak.js → wrap-Bzdimp4p.js} +1 -1
- package/package.json +18 -3
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import z from "@deepseek-ai/schemastery";
|
|
3
|
+
import { CredentialRecord } from "@deepseek-ai/dsh-credentials";
|
|
4
|
+
import { IncomingMessage } from "node:http";
|
|
5
|
+
|
|
6
|
+
//#region src/web-password.d.ts
|
|
7
|
+
|
|
8
|
+
/** Native cookie envelope version. */
|
|
9
|
+
declare const COOKIE_PAYLOAD_VERSION = 1;
|
|
10
|
+
declare const PASSWORD_RECORD_VERSION = 1;
|
|
11
|
+
/** What the native verifier expects inside a browser cookie. */
|
|
12
|
+
interface BrowserCookiePayload {
|
|
13
|
+
readonly version: typeof COOKIE_PAYLOAD_VERSION;
|
|
14
|
+
readonly authority: string;
|
|
15
|
+
readonly issuedAt: number;
|
|
16
|
+
readonly expiresAt: number;
|
|
17
|
+
}
|
|
18
|
+
/** This row's stored password record payload. */
|
|
19
|
+
interface StoredPasswordPayload {
|
|
20
|
+
readonly version: typeof PASSWORD_RECORD_VERSION;
|
|
21
|
+
readonly algorithm: 'scrypt';
|
|
22
|
+
/** base64url salt. */
|
|
23
|
+
readonly salt: string;
|
|
24
|
+
/** base64url derived key. */
|
|
25
|
+
readonly hash: string;
|
|
26
|
+
readonly N: number;
|
|
27
|
+
readonly r: number;
|
|
28
|
+
readonly p: number;
|
|
29
|
+
readonly keylen: number;
|
|
30
|
+
}
|
|
31
|
+
/** base64url-encode bytes without padding (the native cookie's alphabet). */
|
|
32
|
+
declare function encodeBase64Url(value: Uint8Array): string;
|
|
33
|
+
/**
|
|
34
|
+
* Decode a canonical base64url string; non-canonical input is rejected rather
|
|
35
|
+
* than silently normalized, which is what makes a tampered payload fail closed.
|
|
36
|
+
* @param value - the candidate string.
|
|
37
|
+
* @returns the bytes, or `undefined` when it is not canonical base64url.
|
|
38
|
+
*/
|
|
39
|
+
declare function decodeBase64Url(value: string): Buffer | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The native cookie name for one request authority.
|
|
42
|
+
* @param authority - canonical `host` or `host:port`.
|
|
43
|
+
* @returns the cookie name.
|
|
44
|
+
*/
|
|
45
|
+
declare function cookieName(authority: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Mint a native-format browser-session cookie value.
|
|
48
|
+
* @param payload - the session claims.
|
|
49
|
+
* @param secret - the native signing key.
|
|
50
|
+
* @returns `v1.<base64url payload>.<base64url HMAC>`.
|
|
51
|
+
*/
|
|
52
|
+
declare function encodeSessionCookie(payload: BrowserCookiePayload, secret: Buffer): string;
|
|
53
|
+
/**
|
|
54
|
+
* Verify and decode a native-format browser-session cookie value.
|
|
55
|
+
* @param value - the cookie value.
|
|
56
|
+
* @param secret - the native signing key.
|
|
57
|
+
* @returns the claims, or `undefined` when the envelope, signature, or shape fails.
|
|
58
|
+
*/
|
|
59
|
+
declare function decodeSessionCookie(value: string, secret: Buffer): BrowserCookiePayload | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Canonical request authority: the native cookie name and its signed audience.
|
|
62
|
+
* @param headers - the incoming request headers.
|
|
63
|
+
* @returns `host` or `host:port`, lowercased, or `undefined` without a usable Host.
|
|
64
|
+
*/
|
|
65
|
+
declare function requestAuthority(headers: IncomingMessage['headers']): string | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Serialize the fixed browser-session attributes; generated names and values
|
|
68
|
+
* are cookie-safe base64url. Mirrors the native attribute set exactly.
|
|
69
|
+
*/
|
|
70
|
+
declare function sessionCookieHeader(name: string, value: string, expiresAt: number, maxAgeSeconds: number): string;
|
|
71
|
+
/**
|
|
72
|
+
* Verify the native browser cookie on one request, with the native checks:
|
|
73
|
+
* authority binding, issued/expiry window, and a lifetime no longer than ours.
|
|
74
|
+
* @param headers - incoming request headers carrying Host and Cookie.
|
|
75
|
+
* @param secret - the native signing key.
|
|
76
|
+
* @param maxAgeMilliseconds - the longest lifetime this deployment accepts.
|
|
77
|
+
* @returns true only for a live cookie signed by the native key for this authority.
|
|
78
|
+
*/
|
|
79
|
+
declare function sessionAuthenticated(headers: IncomingMessage['headers'], secret: Buffer, maxAgeMilliseconds: number): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Derive the scrypt key for one password.
|
|
82
|
+
* @param password - the submitted password.
|
|
83
|
+
* @param payload - salt and work factors.
|
|
84
|
+
* @returns the derived key.
|
|
85
|
+
*/
|
|
86
|
+
declare function derivePasswordKey(password: string, payload: Pick<StoredPasswordPayload, 'salt' | 'N' | 'r' | 'p' | 'keylen'>): Promise<Buffer>;
|
|
87
|
+
/**
|
|
88
|
+
* Constant-time password check against a stored payload.
|
|
89
|
+
* @param password - the submitted password.
|
|
90
|
+
* @param payload - the stored record.
|
|
91
|
+
* @returns true only on an exact match.
|
|
92
|
+
*/
|
|
93
|
+
declare function verifyPassword(password: string, payload: StoredPasswordPayload): Promise<boolean>;
|
|
94
|
+
/**
|
|
95
|
+
* Build a fresh stored payload for one password (random salt).
|
|
96
|
+
* @param password - the password to store.
|
|
97
|
+
* @returns the payload to write into the credential record.
|
|
98
|
+
*/
|
|
99
|
+
declare function seedPasswordPayload(password: string): Promise<StoredPasswordPayload>;
|
|
100
|
+
/**
|
|
101
|
+
* Interpret one password record; a present-but-unsupported record is loud
|
|
102
|
+
* (fail closed) rather than silently treated as absent.
|
|
103
|
+
* @param record - the stored record, when any.
|
|
104
|
+
* @returns the payload, or `undefined` when no record is stored.
|
|
105
|
+
*/
|
|
106
|
+
declare function parsePasswordPayload(record: CredentialRecord | undefined): StoredPasswordPayload | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* The sign-in page. Server-rendered, self-contained, no external resource: it
|
|
109
|
+
* is the only thing an unauthenticated request ever receives.
|
|
110
|
+
* @param notice - optional failure text.
|
|
111
|
+
* @returns the complete HTML document.
|
|
112
|
+
*/
|
|
113
|
+
declare function loginPage(notice?: string): string;
|
|
114
|
+
/**
|
|
115
|
+
* Insert the relative base the served dist needs, exactly as the native
|
|
116
|
+
* fallback owner does, so every asset reference resolves under the mount.
|
|
117
|
+
* @param html - the rendered index markup.
|
|
118
|
+
* @returns the markup with `<base href="./">` after the head open tag.
|
|
119
|
+
*/
|
|
120
|
+
declare function withBaseHref(html: string): string;
|
|
121
|
+
/** Row config: the only knob is how long a minted session lives. */
|
|
122
|
+
interface WebPasswordConfig {
|
|
123
|
+
/** Absolute browser-session lifetime in days. Default: 30 (the native default). */
|
|
124
|
+
cookieMaxAgeDays?: number;
|
|
125
|
+
}
|
|
126
|
+
declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
127
|
+
cookieMaxAgeDays: z<number, number, "defined">;
|
|
128
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
129
|
+
cookieMaxAgeDays: z<number, number, "defined">;
|
|
130
|
+
}>>, "plain">;
|
|
131
|
+
/** Cordis plugin name; also the scope of this row's credential record. */
|
|
132
|
+
declare const name = "dashr-web-password";
|
|
133
|
+
/**
|
|
134
|
+
* No static injects: the gate is composed around `webServer`, `connection`
|
|
135
|
+
* (which owns the session secret), and `credentials`, so a composition without
|
|
136
|
+
* a browser surface loads this row dormant.
|
|
137
|
+
*/
|
|
138
|
+
declare const inject: string[];
|
|
139
|
+
/**
|
|
140
|
+
* Claim exact `/` and put the password in front of it.
|
|
141
|
+
* @param ctx - host plugin context.
|
|
142
|
+
* @param config - the row config.
|
|
143
|
+
*/
|
|
144
|
+
declare function apply(ctx: Context, config?: WebPasswordConfig): void;
|
|
145
|
+
declare const _default: {
|
|
146
|
+
name: string;
|
|
147
|
+
inject: string[];
|
|
148
|
+
Config: z<Schemastery.ObjectS<NoInfer<{
|
|
149
|
+
cookieMaxAgeDays: z<number, number, "defined">;
|
|
150
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
151
|
+
cookieMaxAgeDays: z<number, number, "defined">;
|
|
152
|
+
}>>, "plain">;
|
|
153
|
+
apply: typeof apply;
|
|
154
|
+
};
|
|
155
|
+
//#endregion
|
|
156
|
+
export { BrowserCookiePayload, Config, StoredPasswordPayload, WebPasswordConfig, apply, cookieName, decodeBase64Url, decodeSessionCookie, _default as default, derivePasswordKey, encodeBase64Url, encodeSessionCookie, inject, loginPage, name, parsePasswordPayload, requestAuthority, seedPasswordPayload, sessionAuthenticated, sessionCookieHeader, verifyPassword, withBaseHref };
|