@shelbyb/daywalker-sdk 0.6.0 → 0.8.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.
- package/README.md +168 -22
- package/dist/cli.js +102 -16
- package/dist/client.d.ts +81 -50
- package/dist/client.js +1015 -201
- package/dist/config.d.ts +12 -1
- package/dist/config.js +34 -2
- package/dist/crypto/digest.js +3 -2
- package/dist/crypto/dpop.d.ts +38 -1
- package/dist/crypto/dpop.js +124 -6
- package/dist/crypto/encoding.js +2 -0
- package/dist/crypto/index.d.ts +6 -4
- package/dist/crypto/index.js +4 -3
- package/dist/crypto/key-api.d.ts +69 -0
- package/dist/crypto/key-api.js +217 -0
- package/dist/crypto/keys.d.ts +5 -0
- package/dist/crypto/keys.js +25 -15
- package/dist/crypto/signatures.d.ts +13 -24
- package/dist/crypto/signatures.js +41 -84
- package/dist/crypto/webcrypto.d.ts +39 -0
- package/dist/crypto/webcrypto.js +26 -0
- package/dist/express.d.ts +2 -1
- package/dist/express.js +12 -32
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/keystore/file.d.ts +14 -0
- package/dist/keystore/file.js +77 -0
- package/dist/keystore/index.d.ts +18 -0
- package/dist/keystore/index.js +71 -0
- package/dist/middleware.d.ts +27 -3
- package/dist/middleware.js +75 -22
- package/dist/next.d.ts +5 -3
- package/dist/next.js +38 -42
- package/dist/types.d.ts +129 -4
- package/package.json +11 -1
- package/dist/signing.d.ts +0 -3
- package/dist/signing.js +0 -2
package/dist/next.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { daywalker, Daywalker } from "./client.js";
|
|
2
|
-
import { toAuthFailureResponse } from "./middleware.js";
|
|
2
|
+
import { readCredentials, toAuthFailureResponse } from "./middleware.js";
|
|
3
3
|
/**
|
|
4
4
|
* Real Server Action IDs are hex hashes. Scanners probing for CVE-2025-55182 (React2Shell)
|
|
5
5
|
* send junk like `Next-Action: x`, which Next.js rejects with an internal error.
|
|
@@ -129,17 +129,23 @@ const REDIRECT_ERROR_CODES = new Set([
|
|
|
129
129
|
"NETWORK_ERROR",
|
|
130
130
|
"SERVICE_UNAVAILABLE",
|
|
131
131
|
"CONFIGURATION_ERROR",
|
|
132
|
+
"SERVICE_NOT_GRANTED",
|
|
133
|
+
"DPOP_REQUIRED",
|
|
134
|
+
"INVALID_DPOP_PROOF",
|
|
132
135
|
]);
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return null;
|
|
136
|
+
function credentialsOf(req) {
|
|
137
|
+
return readCredentials((name) => req.headers.get(name), { method: req.method, url: req.url });
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Next's "continue" and redirect responses, built here rather than through a `NextResponse` found on
|
|
141
|
+
* `globalThis`: anything in the process could plant one there and turn a failed check into a pass.
|
|
142
|
+
* `x-middleware-next: 1` is exactly what `NextResponse.next()` sends.
|
|
143
|
+
*/
|
|
144
|
+
function continueResponse() {
|
|
145
|
+
return new Response(null, { headers: { "x-middleware-next": "1" } });
|
|
146
|
+
}
|
|
147
|
+
function redirectResponse(url) {
|
|
148
|
+
return Response.redirect(url.toString(), 307);
|
|
143
149
|
}
|
|
144
150
|
/**
|
|
145
151
|
* Hardened Next.js Middleware for root `middleware.ts`.
|
|
@@ -147,7 +153,8 @@ function extractToken(req) {
|
|
|
147
153
|
* Implements:
|
|
148
154
|
* 1. Server Action probe defense (CVE-2025-55182 scanner mitigation)
|
|
149
155
|
* 2. Static asset and health check bypass
|
|
150
|
-
* 3. Per-request token auth: requests without `Authorization: Bearer` / `
|
|
156
|
+
* 3. Per-request token auth: requests without `Authorization: Bearer` / `Authorization: DPoP` (with its
|
|
157
|
+
* proof) / `x-api-token` get 401
|
|
151
158
|
* 4. Distinct handling for API routes (JSON + CORS) vs UI pages (redirect to `errorPath` with `from`)
|
|
152
159
|
*
|
|
153
160
|
* Only `/_next/static/`, `/_next/image`, `/favicon.ico` and `bypassPaths` skip auth by default.
|
|
@@ -166,21 +173,22 @@ function extractToken(req) {
|
|
|
166
173
|
export function createDaywalkerMiddleware(options = {}) {
|
|
167
174
|
const client = options.client ?? daywalker;
|
|
168
175
|
return buildMiddleware(options, async (request) => {
|
|
169
|
-
const
|
|
170
|
-
if (!
|
|
171
|
-
return { ok: false, error: "INVALID_TOKEN", status: 401, message:
|
|
176
|
+
const credentials = credentialsOf(request);
|
|
177
|
+
if (!credentials.ok) {
|
|
178
|
+
return { ok: false, error: "INVALID_TOKEN", status: 401, message: credentials.message };
|
|
172
179
|
}
|
|
173
|
-
return client.validateToken(token, { serviceSlug: options.serviceSlug });
|
|
180
|
+
return client.validateToken(credentials.token, { serviceSlug: options.serviceSlug, dpop: credentials.dpop });
|
|
174
181
|
});
|
|
175
182
|
}
|
|
176
183
|
/**
|
|
177
|
-
* Service health gate: checks this service's
|
|
178
|
-
* routes every request to `errorPath` while
|
|
184
|
+
* Service health gate: checks that this service's OAuth client credentials still get an access token
|
|
185
|
+
* covering its service (not the caller's token) and routes every request to `errorPath` while they don't,
|
|
186
|
+
* redirecting back once it heals.
|
|
179
187
|
* It does NOT authenticate callers; use `createDaywalkerMiddleware` or `withDaywalkerAuth` for that.
|
|
180
188
|
*/
|
|
181
189
|
export function createDaywalkerServiceHealthMiddleware(options = {}) {
|
|
182
190
|
const client = options.client ?? daywalker;
|
|
183
|
-
return buildMiddleware(options, () => client.
|
|
191
|
+
return buildMiddleware(options, () => client.validateServiceCredentials({ serviceSlug: options.serviceSlug }));
|
|
184
192
|
}
|
|
185
193
|
function buildMiddleware(options, authenticate) {
|
|
186
194
|
const bypassPaths = options.bypassPaths ?? DEFAULT_BYPASS_PATHS;
|
|
@@ -215,9 +223,7 @@ function buildMiddleware(options, authenticate) {
|
|
|
215
223
|
// 1. Bypass static files and health check probes
|
|
216
224
|
if (pathname !== null &&
|
|
217
225
|
(bypassPaths.some((path) => pathname === path || pathname.startsWith(`${path}/`)) || isStaticNormalized(pathname, matchesExtension))) {
|
|
218
|
-
return
|
|
219
|
-
? globalThis.NextResponse.next()
|
|
220
|
-
: new Response(null, { headers: { "x-middleware-next": "1" } });
|
|
226
|
+
return continueResponse();
|
|
221
227
|
}
|
|
222
228
|
// 2. Authenticate (caller's token, or the service key for the health gate)
|
|
223
229
|
const authResult = await authenticate(request);
|
|
@@ -226,14 +232,10 @@ function buildMiddleware(options, authenticate) {
|
|
|
226
232
|
if (authResult.ok) {
|
|
227
233
|
// Authorized again: heal/redirect back to home
|
|
228
234
|
const redirectUrl = new URL(homePath, request.url);
|
|
229
|
-
return
|
|
230
|
-
? globalThis.NextResponse.redirect(redirectUrl)
|
|
231
|
-
: Response.redirect(redirectUrl.toString(), 307);
|
|
235
|
+
return redirectResponse(redirectUrl);
|
|
232
236
|
}
|
|
233
237
|
// Allow rendering the error page
|
|
234
|
-
return
|
|
235
|
-
? globalThis.NextResponse.next()
|
|
236
|
-
: new Response(null, { headers: { "x-middleware-next": "1" } });
|
|
238
|
+
return continueResponse();
|
|
237
239
|
}
|
|
238
240
|
// 4. Handle invalid token for all other routes
|
|
239
241
|
if (!authResult.ok) {
|
|
@@ -250,16 +252,14 @@ function buildMiddleware(options, authenticate) {
|
|
|
250
252
|
"Content-Type": "application/json",
|
|
251
253
|
"Access-Control-Allow-Origin": "*",
|
|
252
254
|
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
253
|
-
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Api-Token",
|
|
255
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization, DPoP, X-Api-Token",
|
|
254
256
|
...(failure.retryAfter ? { "Retry-After": String(failure.retryAfter) } : {}),
|
|
255
257
|
},
|
|
256
258
|
});
|
|
257
259
|
}
|
|
258
260
|
// If user only wanted API protection, allow web routes through
|
|
259
261
|
if (options.protectApiOnly) {
|
|
260
|
-
return
|
|
261
|
-
? globalThis.NextResponse.next()
|
|
262
|
-
: new Response(null, { headers: { "x-middleware-next": "1" } });
|
|
262
|
+
return continueResponse();
|
|
263
263
|
}
|
|
264
264
|
// Web UI routes: redirect to diagnostic service error screen. Only a fixed error code and
|
|
265
265
|
// status are passed: the free-text message may carry server details and would let anyone
|
|
@@ -274,13 +274,9 @@ function buildMiddleware(options, authenticate) {
|
|
|
274
274
|
redirectUrl.searchParams.set("from", sanitized);
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
|
-
return
|
|
278
|
-
? globalThis.NextResponse.redirect(redirectUrl)
|
|
279
|
-
: Response.redirect(redirectUrl.toString(), 307);
|
|
277
|
+
return redirectResponse(redirectUrl);
|
|
280
278
|
}
|
|
281
|
-
return
|
|
282
|
-
? globalThis.NextResponse.next()
|
|
283
|
-
: new Response(null, { headers: { "x-middleware-next": "1" } });
|
|
279
|
+
return continueResponse();
|
|
284
280
|
};
|
|
285
281
|
}
|
|
286
282
|
/**
|
|
@@ -303,11 +299,11 @@ export function withDaywalkerAuth(handler, clientOrOptions) {
|
|
|
303
299
|
: clientOrOptions?.client ?? daywalker;
|
|
304
300
|
const serviceSlug = !(clientOrOptions instanceof Daywalker) ? clientOrOptions?.serviceSlug : undefined;
|
|
305
301
|
return async function daywalkerAuthHandler(req, context) {
|
|
306
|
-
const
|
|
307
|
-
if (!
|
|
308
|
-
return Response.json({ error: "INVALID_TOKEN", message:
|
|
302
|
+
const credentials = credentialsOf(req);
|
|
303
|
+
if (!credentials.ok) {
|
|
304
|
+
return Response.json({ error: "INVALID_TOKEN", message: credentials.message }, { status: 401 });
|
|
309
305
|
}
|
|
310
|
-
const result = await client.validateToken(token, { serviceSlug });
|
|
306
|
+
const result = await client.validateToken(credentials.token, { serviceSlug, dpop: credentials.dpop });
|
|
311
307
|
if (!result.ok) {
|
|
312
308
|
const { status, ...body } = toAuthFailureResponse(result);
|
|
313
309
|
return Response.json(body, {
|
package/dist/types.d.ts
CHANGED
|
@@ -20,7 +20,25 @@ export interface TokenPayload {
|
|
|
20
20
|
offlineVerified?: boolean;
|
|
21
21
|
[key: string]: unknown;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
/** The DPoP proof that came with an incoming `Authorization: DPoP <token>` request. */
|
|
24
|
+
export interface IncomingDpop {
|
|
25
|
+
/** The `DPoP` header. */
|
|
26
|
+
proof: string | null | undefined;
|
|
27
|
+
method: string;
|
|
28
|
+
/** The full request URL (its origin is replaced by `publicOrigin` when configured). */
|
|
29
|
+
url: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ValidateTokenOptions {
|
|
32
|
+
serviceSlug?: string;
|
|
33
|
+
forceRefresh?: boolean;
|
|
34
|
+
offlineOnly?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The request's DPoP proof. Required to accept a DPoP-bound (`cnf.jkt`) access token; the adapters pass
|
|
37
|
+
* it for you. A bound token without a valid proof is refused with DPOP_REQUIRED / INVALID_DPOP_PROOF.
|
|
38
|
+
*/
|
|
39
|
+
dpop?: IncomingDpop;
|
|
40
|
+
}
|
|
41
|
+
export type ValidateErrorCode = "EXPIRED" | "REVOKED" | "INVALID_TOKEN" | "RATE_LIMITED" | "NETWORK_ERROR" | "SERVICE_UNAVAILABLE" | "CONFIGURATION_ERROR" | "SERVICE_NOT_GRANTED" | "DPOP_REQUIRED" | "INVALID_DPOP_PROOF" | string;
|
|
24
42
|
/**
|
|
25
43
|
* Failures that say nothing about the token: Daywalker Auth was unreachable, timed out, answered 5xx
|
|
26
44
|
* or answered with something that isn't a validation result. Both carry status 503 and are never cached;
|
|
@@ -72,7 +90,49 @@ export interface RetryOptions {
|
|
|
72
90
|
*/
|
|
73
91
|
retryNetworkErrors?: boolean;
|
|
74
92
|
}
|
|
93
|
+
/** A provisioned signing key as a `KeyStore` keeps it. Only keys already registered with Daywalker are stored. */
|
|
94
|
+
export interface StoredSigningKey {
|
|
95
|
+
/** Record format version (1). */
|
|
96
|
+
version: 1;
|
|
97
|
+
/** RFC 7638 thumbprint of the public key; checked against the key on every load. */
|
|
98
|
+
keyId: string;
|
|
99
|
+
/** The domain the key is registered for. */
|
|
100
|
+
domain: string;
|
|
101
|
+
/** The Ed25519 private key, PKCS#8 DER in base64. */
|
|
102
|
+
privateKeyPkcs8Base64: string;
|
|
103
|
+
/** Unix seconds when it was registered. */
|
|
104
|
+
createdAt: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Where an auto-provisioned signing key lives between processes. On first use the client loads it; when
|
|
108
|
+
* there is none it generates a key, registers it with Daywalker (`POST /api/v1/keys/register`) and saves it
|
|
109
|
+
* with `saveIfAbsent`, which must be atomic (create-if-absent): when several instances start at once exactly
|
|
110
|
+
* one save wins and the others load the winner's key. A store without `saveIfAbsent` is read-only.
|
|
111
|
+
* Built in: `memoryKeyStore()` / `envKeyStore()` (`@shelbyb/daywalker-sdk/keystore`) and `fileKeyStore()`
|
|
112
|
+
* (`@shelbyb/daywalker-sdk/keystore/file`); Redis (`SET key value NX`), KV or a secrets manager fit too.
|
|
113
|
+
*/
|
|
114
|
+
export interface KeyStore {
|
|
115
|
+
load(): Promise<StoredSigningKey | null> | StoredSigningKey | null;
|
|
116
|
+
/** Saves `key` unless one is already stored. True when this call saved it, false when another key was there. */
|
|
117
|
+
saveIfAbsent?(key: StoredSigningKey): Promise<boolean> | boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Signs with a key held elsewhere, typically a KMS or HSM, so the private key never exists in this process,
|
|
121
|
+
* its environment or its files. `sign` receives the RFC 9421 signature base and must return the raw 64-byte
|
|
122
|
+
* Ed25519 signature. Register the public key once (`registerPublicKey`); pass `publicJwk` so the first
|
|
123
|
+
* signature is checked against it before anything is sent.
|
|
124
|
+
*/
|
|
125
|
+
export interface MessageSigner {
|
|
126
|
+
/** The registered key's id (its RFC 7638 thumbprint, or the id you registered it under). */
|
|
127
|
+
keyId: string;
|
|
128
|
+
sign(data: Uint8Array): Promise<Uint8Array>;
|
|
129
|
+
publicJwk?: PublicJwk;
|
|
130
|
+
}
|
|
75
131
|
export interface DaywalkerConfig {
|
|
132
|
+
/**
|
|
133
|
+
* The OAuth client credential (env DAYWALKER_API_KEY). Sent only on the client credentials grant to
|
|
134
|
+
* `POST /api/v1/oauth/token`; every other request carries a DPoP-bound access token.
|
|
135
|
+
*/
|
|
76
136
|
apiKey?: string;
|
|
77
137
|
signingKey?: string | SigningKey;
|
|
78
138
|
/**
|
|
@@ -91,6 +151,12 @@ export interface DaywalkerConfig {
|
|
|
91
151
|
domain?: string;
|
|
92
152
|
/** A JWK, a JWKS (`{ keys: [...] }`, selected by the lease's `kid`), PEM, or Base64 SPKI / raw key. */
|
|
93
153
|
daywalkerPublicKey?: string | PublicJwk | PublicJwks;
|
|
154
|
+
/**
|
|
155
|
+
* `"auto"` (env DAYWALKER_JWKS=auto) verifies access tokens offline against Daywalker's published key set,
|
|
156
|
+
* fetched from `${authUrl}/.well-known/jwks.json` only and cached, so signing-key rotation needs no
|
|
157
|
+
* redeploy. When no key set can be obtained, `daywalkerPublicKey` (if set) is used instead. Default off.
|
|
158
|
+
*/
|
|
159
|
+
jwks?: "auto" | "off";
|
|
94
160
|
/**
|
|
95
161
|
* Expected `iss` of offline-verified JWT leases (env DAYWALKER_LEASE_ISSUER). Daywalker documents no fixed
|
|
96
162
|
* issuer, so `iss` is unchecked when unset; set it whenever leases from other issuers could share your key.
|
|
@@ -104,6 +170,34 @@ export interface DaywalkerConfig {
|
|
|
104
170
|
maxRetries?: number;
|
|
105
171
|
/** Defaults for `fetch()` retries; per-request `init.retry` overrides individual fields. */
|
|
106
172
|
retry?: RetryOptions;
|
|
173
|
+
/**
|
|
174
|
+
* Origin clients use to reach this service (e.g. `https://api.example.com`), for checking the `htu` of
|
|
175
|
+
* DPoP proofs that come with bound access tokens. Defaults to the request URL's origin; set it behind a
|
|
176
|
+
* proxy or load balancer that rewrites the host.
|
|
177
|
+
*/
|
|
178
|
+
publicOrigin?: string;
|
|
179
|
+
/** Shared store for DPoP proof `jti`s (default: per-process memory). Needed with several instances. */
|
|
180
|
+
dpopReplayStore?: ReplayStore;
|
|
181
|
+
/**
|
|
182
|
+
* Auto-provisioning: where the signing key is kept when `signingKey` / DAYWALKER_SIGNING_KEY isn't set.
|
|
183
|
+
* On first use the client loads it from here, or generates one, registers it for `domain` with the API key
|
|
184
|
+
* and saves it. Ignored when `signingKey` or `signer` is set.
|
|
185
|
+
*/
|
|
186
|
+
keyStore?: KeyStore;
|
|
187
|
+
/**
|
|
188
|
+
* Ephemeral signing keys (env DAYWALKER_EPHEMERAL_KEY=true): the key is generated in memory, non-extractable,
|
|
189
|
+
* registered for `domain` with a lifetime (`ttlSeconds`, default 6 hours; env DAYWALKER_KEY_TTL_SECONDS) in
|
|
190
|
+
* this process's own slot (`instanceId`, default random; env DAYWALKER_INSTANCE_ID), and replaced in the
|
|
191
|
+
* same slot before it expires. Nothing is stored anywhere. `close()` revokes it at shutdown. Daywalker allows
|
|
192
|
+
* 20 live keys per domain, so give long-lived instances a stable `instanceId` (a restart then replaces its
|
|
193
|
+
* previous key) and prefer a shared `keyStore` for serverless. Can't be combined with `keyStore`.
|
|
194
|
+
*/
|
|
195
|
+
ephemeralKey?: boolean | {
|
|
196
|
+
ttlSeconds?: number;
|
|
197
|
+
instanceId?: string;
|
|
198
|
+
};
|
|
199
|
+
/** Signs requests with an external key (KMS / HSM) instead of a local one. Takes precedence over everything. */
|
|
200
|
+
signer?: MessageSigner;
|
|
107
201
|
/** Per-attempt timeout for requests to Daywalker Auth. Default 5000ms; 0 disables. */
|
|
108
202
|
timeoutMs?: number;
|
|
109
203
|
fetch?: typeof fetch;
|
|
@@ -126,6 +220,36 @@ export interface TokenSet {
|
|
|
126
220
|
services: string[];
|
|
127
221
|
jwksUri?: string;
|
|
128
222
|
}
|
|
223
|
+
/** A service's license key from Daywalker: derived per service, signing key and one-hour window. */
|
|
224
|
+
export interface License {
|
|
225
|
+
serviceSlug: string;
|
|
226
|
+
/** 64 hex characters (32 bytes). A secret: never log it or send it anywhere. */
|
|
227
|
+
licenseKey: string;
|
|
228
|
+
/** ISO 8601: the end of the window the key is valid for. */
|
|
229
|
+
expiresAt: string;
|
|
230
|
+
}
|
|
231
|
+
/** The config bundle Daywalker seals under the license key. Fields beyond these are passed through. */
|
|
232
|
+
export interface ConfigBundle {
|
|
233
|
+
serviceSlug: string;
|
|
234
|
+
/** Random per issue; derive per-process secrets from it (and the license key), never store it. */
|
|
235
|
+
dataKeySalt: string;
|
|
236
|
+
features: {
|
|
237
|
+
exclusiveTier?: boolean;
|
|
238
|
+
stage?: string;
|
|
239
|
+
rateLimitPerMinute?: number | null;
|
|
240
|
+
rateLimitPerHour?: number | null;
|
|
241
|
+
[key: string]: unknown;
|
|
242
|
+
};
|
|
243
|
+
issuedAt: string;
|
|
244
|
+
expiresAt: string;
|
|
245
|
+
[key: string]: unknown;
|
|
246
|
+
}
|
|
247
|
+
export interface LicenseOptions {
|
|
248
|
+
/** Default: the configured service slug. */
|
|
249
|
+
serviceSlug?: string;
|
|
250
|
+
/** Ignore the cached license and start a new client credentials grant. */
|
|
251
|
+
forceRefresh?: boolean;
|
|
252
|
+
}
|
|
129
253
|
export interface GetTokensOptions {
|
|
130
254
|
/** Narrow the grant to these service slugs (least privilege); default: every service the credentials cover. */
|
|
131
255
|
scope?: string[];
|
|
@@ -162,12 +286,13 @@ export interface SignRequestParams {
|
|
|
162
286
|
path: string;
|
|
163
287
|
authority: string;
|
|
164
288
|
body?: string | Uint8Array | null;
|
|
165
|
-
key
|
|
289
|
+
/** The local key to sign with. Not needed (and ignored) when `signer` is given. */
|
|
290
|
+
key?: SigningKey | string;
|
|
291
|
+
/** Signs with an external key instead (KMS / HSM); `keyid` defaults to `signer.keyId`. */
|
|
292
|
+
signer?: MessageSigner;
|
|
166
293
|
created?: number;
|
|
167
294
|
keyid?: string;
|
|
168
295
|
alg?: string;
|
|
169
|
-
/** Sets `Authorization: Bearer <apiKey>` on the returned headers (not covered by the signature). */
|
|
170
|
-
apiKey?: string;
|
|
171
296
|
/** Must be 1-128 of `[A-Za-z0-9_.-]` so it can't inject Signature-Input parameters. */
|
|
172
297
|
nonce?: string;
|
|
173
298
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shelbyb/daywalker-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Daywalker Auth service validation plus the DevPulse client SDKs (feature flags, OpenFeature, product analytics) in one package with a single runtime dependency (re2js).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,6 +26,16 @@
|
|
|
26
26
|
"import": "./dist/express.js",
|
|
27
27
|
"default": "./dist/express.js"
|
|
28
28
|
},
|
|
29
|
+
"./keystore": {
|
|
30
|
+
"types": "./dist/keystore/index.d.ts",
|
|
31
|
+
"import": "./dist/keystore/index.js",
|
|
32
|
+
"default": "./dist/keystore/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./keystore/file": {
|
|
35
|
+
"types": "./dist/keystore/file.d.ts",
|
|
36
|
+
"import": "./dist/keystore/file.js",
|
|
37
|
+
"default": "./dist/keystore/file.js"
|
|
38
|
+
},
|
|
29
39
|
"./flags": {
|
|
30
40
|
"types": "./dist/flags/client.d.ts",
|
|
31
41
|
"import": "./dist/flags/client.js",
|
package/dist/signing.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { stringToUtf8, utf8ToString, bytesToBase64, base64ToBytes, bytesToBase64Url, base64UrlToBytes, bytesToHex, hexToBytes, computeContentDigest, sha256Base64, sha256Base64Url, calculateJwkThumbprint, generateSigningKey, loadSigningKey, loadPublicKey, SIGNATURE_VERSION, SIGNATURE_LABEL, SIGNATURE_ALG, MAX_CLOCK_SKEW_SECONDS, formatSignatureParams, createSignatureBase, signRequest, verifyRequestSignature, verifyJwtLease, registerPublicKey, } from "./crypto/index.js";
|
|
2
|
-
export declare const KEYS_PATH = "/.well-known/daywalker-keys.json";
|
|
3
|
-
export type { PublicJwk, SigningKey, SignedHeaders, SignRequestParams, VerifySignatureParams, VerifySignatureResult, } from "./types.js";
|
package/dist/signing.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export { stringToUtf8, utf8ToString, bytesToBase64, base64ToBytes, bytesToBase64Url, base64UrlToBytes, bytesToHex, hexToBytes, computeContentDigest, sha256Base64, sha256Base64Url, calculateJwkThumbprint, generateSigningKey, loadSigningKey, loadPublicKey, SIGNATURE_VERSION, SIGNATURE_LABEL, SIGNATURE_ALG, MAX_CLOCK_SKEW_SECONDS, formatSignatureParams, createSignatureBase, signRequest, verifyRequestSignature, verifyJwtLease, registerPublicKey, } from "./crypto/index.js";
|
|
2
|
-
export const KEYS_PATH = "/.well-known/daywalker-keys.json";
|