pipework 0.60.0 → 0.62.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/CHANGELOG.md +14 -0
- package/REFERENCE.md +26 -0
- package/dist/REFERENCE.md +67 -3
- package/dist/auth/auth/index.d.ts +4 -0
- package/dist/auth/auth/index.d.ts.map +1 -1
- package/dist/auth/auth/index.js +2 -0
- package/dist/auth/auth/index.js.map +1 -1
- package/dist/auth/auth/multi-org.d.ts +8 -1
- package/dist/auth/auth/multi-org.d.ts.map +1 -1
- package/dist/auth/auth/multi-org.js +9 -1
- package/dist/auth/auth/multi-org.js.map +1 -1
- package/dist/auth/auth/namespace.d.ts +6 -0
- package/dist/auth/auth/namespace.d.ts.map +1 -1
- package/dist/auth/auth/namespace.js +6 -0
- package/dist/auth/auth/namespace.js.map +1 -1
- package/dist/auth/auth/passwords.d.ts +39 -0
- package/dist/auth/auth/passwords.d.ts.map +1 -0
- package/dist/auth/auth/passwords.js +76 -0
- package/dist/auth/auth/passwords.js.map +1 -0
- package/dist/auth/auth/schema.d.ts +104 -0
- package/dist/auth/auth/schema.d.ts.map +1 -0
- package/dist/auth/auth/schema.js +66 -0
- package/dist/auth/auth/schema.js.map +1 -0
- package/dist/auth/auth/sessions.d.ts +4 -1
- package/dist/auth/auth/sessions.d.ts.map +1 -1
- package/dist/auth/auth/sessions.js +6 -1
- package/dist/auth/auth/sessions.js.map +1 -1
- package/dist/auth/auth/sign-in.d.ts +64 -0
- package/dist/auth/auth/sign-in.d.ts.map +1 -0
- package/dist/auth/auth/sign-in.js +135 -0
- package/dist/auth/auth/sign-in.js.map +1 -0
- package/dist/auth/auth/uuid.d.ts +3 -0
- package/dist/auth/auth/uuid.d.ts.map +1 -0
- package/dist/auth/auth/uuid.js +9 -0
- package/dist/auth/auth/uuid.js.map +1 -0
- package/dist/core/config/namespace.d.ts +3 -0
- package/dist/core/config/namespace.d.ts.map +1 -1
- package/dist/core/config/schema.d.ts +3 -0
- package/dist/core/config/schema.d.ts.map +1 -1
- package/dist/core/config/schema.js +6 -0
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/errors/http.d.ts +6 -0
- package/dist/core/errors/http.d.ts.map +1 -1
- package/dist/core/errors/http.js +9 -0
- package/dist/core/errors/http.js.map +1 -1
- package/dist/core/errors/index.d.ts +1 -1
- package/dist/core/errors/index.d.ts.map +1 -1
- package/dist/core/errors/index.js +1 -1
- package/dist/core/errors/index.js.map +1 -1
- package/dist/core/errors/namespace.d.ts +3 -1
- package/dist/core/errors/namespace.d.ts.map +1 -1
- package/dist/core/errors/namespace.js +3 -1
- package/dist/core/errors/namespace.js.map +1 -1
- package/dist/data/migrate/generate.d.ts +1 -0
- package/dist/data/migrate/generate.d.ts.map +1 -1
- package/dist/data/migrate/generate.js +15 -1
- package/dist/data/migrate/generate.js.map +1 -1
- package/dist/data/migrate/internal-definitions.d.ts.map +1 -1
- package/dist/data/migrate/internal-definitions.js +13 -0
- package/dist/data/migrate/internal-definitions.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/request/http/server.d.ts.map +1 -1
- package/dist/request/http/server.js +3 -0
- package/dist/request/http/server.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.62.0
|
|
4
|
+
|
|
5
|
+
**Schema note: blueprint `passwords: {}` adds `pipework_signin_attempts` to generated migrations (`key` text primary key, `failures`, `first_failure_at`, `last_failure_at`, `locked_until`; not tenant-scoped). Run `pipework generate` and `pipework migrate` to add it.**
|
|
6
|
+
|
|
7
|
+
- **New: `auth.passwords` hashes and verifies passwords.** scrypt with a PHC-string hash that records its parameters, constant-time verify, and `needsRehash` when the configured parameters were raised. No composition rules; passwords up to 4096 bytes (long passphrases, pasted passwords) work. `verifyNone` costs the same as a wrong password, so an unknown account is not distinguishable by timing.
|
|
8
|
+
- **New: `auth.signIn` slows, then refuses, repeated failed sign-ins.** `attempt({ account, client?, password, lookup })` runs in the current Flow but outside the request transaction, so a route can throw `UnauthorizedError` and the count stays. Attempts are counted per account and per client address in Postgres (shared across processes, surviving restarts) before the password is checked, so parallel guesses are locked out; past the threshold each failure locks for a doubling, capped time and attempts are refused with `retryAfterSeconds`. A success resets the account's count. Failures, refusals and successes are logged and audited (`SignIn`: `fail`, `locked`, `success`).
|
|
9
|
+
- **New: `errors.TooManyRequests` (`TooManyRequestsError`, 429).** The HTTP server sends `Retry-After` when an error carries `retryAfterSeconds`.
|
|
10
|
+
|
|
11
|
+
## 0.61.0
|
|
12
|
+
|
|
13
|
+
**Schema note: apps using `auth.createSessions` / `auth.createMultiOrg` can now get their tables from `pipework generate`. Existing tables from the hand-copied SQL keep working (the statements are `IF NOT EXISTS`); to type their ids uuid, run `ALTER TABLE pipework_refresh_tokens ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid` and `ALTER TABLE pipework_user_orgs ALTER COLUMN org_id TYPE uuid USING org_id::uuid` once.**
|
|
14
|
+
|
|
15
|
+
- **New: blueprint `sessions: {}` and `orgs: {}` put the session and multi-org tables in generated migrations.** `sessions` adds `pipework_refresh_tokens` and `pipework_auth_versions`; `orgs` adds `pipework_user_orgs`. `tenant_id` and `org_id` are uuid, so an org id can be the tenant id; a `tenantId` or `orgId` that is not a uuid now throws a `ValidationError` instead of a Postgres cast error. The tables are not tenant-scoped (refresh lookup and sign-in read across tenants). A custom `createMultiOrg({ table })` stays the app's own DDL.
|
|
16
|
+
|
|
3
17
|
## 0.60.0
|
|
4
18
|
|
|
5
19
|
**Schema note: `audit_record` gains a nullable `entity_id` column and an index on `(tenant_id, entity, entity_id, occurred_at, id)`. `pipework migrate` adds both.**
|
package/REFERENCE.md
CHANGED
|
@@ -284,10 +284,32 @@ Authentication namespace — session management, multi-org support, auth chain r
|
|
|
284
284
|
|
|
285
285
|
Creates a Sessions manager with JWT access/refresh tokens, rotation, and reuse detection.
|
|
286
286
|
|
|
287
|
+
Opt in with blueprint `sessions: {}`. The generated migration then includes `pipework_refresh_tokens` and `pipework_auth_versions`. `user_id` is text (the app's id format); `tenant_id` is uuid, and `tenantId` passed to `issueTokens` must be a uuid or it throws a `ValidationError`. `pipework_refresh_tokens` is deliberately not tenant-scoped: a refresh is looked up by its token hash before any tenant is known. The statements are `IF NOT EXISTS`, so apps that created these tables by hand keep working; if yours has `tenant_id text` holding uuids, run once: `ALTER TABLE pipework_refresh_tokens ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid`.
|
|
288
|
+
|
|
287
289
|
### `auth.createMultiOrg`
|
|
288
290
|
|
|
289
291
|
Creates multi-org session management — org selection, switching, membership CRUD.
|
|
290
292
|
|
|
293
|
+
Opt in with blueprint `orgs: {}` (plus `sessions: {}`). The generated migration then includes `pipework_user_orgs` (`user_id` text, `org_id` uuid, `role`, `joined_at`, `added_by`, unique on `(user_id, org_id)`). It is deliberately not tenant-scoped: a user's orgs are read across orgs at sign-in. An `orgId` that is not a uuid throws a `ValidationError`. The statements are `IF NOT EXISTS`; if your existing table has `org_id text` holding uuids, run once: `ALTER TABLE pipework_user_orgs ALTER COLUMN org_id TYPE uuid USING org_id::uuid`. The definition is for the default table name only: with a custom `table`, the app owns that table's DDL.
|
|
294
|
+
|
|
295
|
+
### `auth.passwords`
|
|
296
|
+
|
|
297
|
+
Hashes and verifies passwords with scrypt; reports when a stored hash needs rehashing.
|
|
298
|
+
|
|
299
|
+
`auth.passwords({ scrypt?: { ln, r, p } })` returns `{ hash, verify, verifyNone }`. Defaults are `ln=15, r=8, p=3`. `hash(password)` returns a PHC string `$scrypt$ln=15,r=8,p=3$<salt>$<hash>` (16-byte salt, 32-byte key). Passwords are NFC-normalized; there are no composition rules, and up to 4096 bytes of UTF-8 are accepted (more throws a `ValidationError`), so long passphrases and pasted passwords work. `verify(stored, password)` compares in constant time and returns `{ ok, needsRehash }`; `needsRehash` is true when the password matched but the stored parameters differ from the configured ones. A malformed stored string returns `ok: false` and logs an error. `verifyNone(password)` spends the cost of a verify against a fixed dummy hash, so an unknown account takes as long as a wrong password.
|
|
300
|
+
|
|
301
|
+
### `auth.signIn`
|
|
302
|
+
|
|
303
|
+
Guarded password sign-in that slows, then refuses, repeated failures per account and per client.
|
|
304
|
+
|
|
305
|
+
Opt in with blueprint `passwords: {}`; the generated migration adds `pipework_signin_attempts` (`key` text primary key, `failures`, `first_failure_at`, `last_failure_at`, `locked_until`), `IF NOT EXISTS`, not tenant-scoped (a sign-in happens before any tenant is known). Counts live in Postgres, so they survive restarts and are shared across processes. `attempt` needs an active Flow and runs every statement on `pipe.system()`, outside the request transaction, so the count is kept even when the route answers a bad password by throwing `UnauthorizedError`.
|
|
306
|
+
|
|
307
|
+
`auth.signIn({ passwords, accountThreshold = 5, clientThreshold = 20, windowSeconds = 900, maxLockSeconds = 900 })` returns `{ attempt({ account, client?, password, lookup }) }`, where `lookup(db, account)` (given `pipe.system()`, a pre-tenant read) returns `{ userId, passwordHash }` or `null`. The result is `{ ok: true, userId, needsRehash }` or `{ ok: false, reason: 'invalid' | 'locked', retryAfterSeconds? }`. An unknown account runs a dummy verify and is reported as `'invalid'`, exactly like a wrong password. Keys are `account:<sha256 of the NFC-lowercased trimmed account>` and `client:<client>` (omitted when no client is given). At or above its threshold, each further failure locks the key for `2^(failures - threshold)` seconds, capped at `maxLockSeconds`; a failure more than `windowSeconds` after the first restarts the count. Each attempt is counted, atomically per key, before the password is checked, so a burst of parallel guesses is locked out rather than all verified. While any key is locked an attempt returns `reason: 'locked'` with `retryAfterSeconds` at once, without checking the password. A success deletes the account key and gives the client key its count back.
|
|
308
|
+
|
|
309
|
+
Tradeoff: locking is per account, so anyone who knows an account name can lock it out by failing on purpose. Each lock is capped (15 minutes by default), and the client key limits how fast one address can do it.
|
|
310
|
+
|
|
311
|
+
Every success, failure and refusal is logged, and audited (entity `SignIn`, verbs `success`, `fail`, `locked`; `entity_id` is the user id when known; `after` holds `accountKey`, `client`, `failures`, `retryAfterSeconds`, never the account string or password) when the Flow has an open trace step. For a route, turn a locked result into a 429 with `throw new errors.TooManyRequests(result.retryAfterSeconds)`.
|
|
312
|
+
|
|
291
313
|
### `auth.runChain`
|
|
292
314
|
|
|
293
315
|
Executes an auth chain (strategy pipeline) to resolve auth + tenant from a request.
|
|
@@ -582,6 +604,10 @@ Base error class with code, statusCode, and suggestion fields.
|
|
|
582
604
|
|
|
583
605
|
409 — resource state conflict (duplicate, version mismatch).
|
|
584
606
|
|
|
607
|
+
### `errors.TooManyRequests`
|
|
608
|
+
|
|
609
|
+
429 — too many attempts; carries `retryAfterSeconds`, sent as a `Retry-After` header.
|
|
610
|
+
|
|
585
611
|
## lifecycle — Startup & Shutdown
|
|
586
612
|
|
|
587
613
|
Application lifecycle namespace — startup orchestration with hooks and timeouts.
|
package/dist/REFERENCE.md
CHANGED
|
@@ -277,6 +277,14 @@ Creates a Sessions manager with JWT access/refresh tokens, rotation, and reuse d
|
|
|
277
277
|
|
|
278
278
|
Creates multi-org session management — org selection, switching, membership CRUD.
|
|
279
279
|
|
|
280
|
+
### `auth.passwords`
|
|
281
|
+
|
|
282
|
+
Hashes and verifies passwords with scrypt; reports when a stored hash needs rehashing.
|
|
283
|
+
|
|
284
|
+
### `auth.signIn`
|
|
285
|
+
|
|
286
|
+
Guarded password sign-in that slows, then refuses, repeated failures per account and per client.
|
|
287
|
+
|
|
280
288
|
### `auth.runChain`
|
|
281
289
|
|
|
282
290
|
Executes an auth chain (strategy pipeline) to resolve auth + tenant from a request.
|
|
@@ -377,6 +385,54 @@ interface Sessions
|
|
|
377
385
|
interface CookieConfig
|
|
378
386
|
```
|
|
379
387
|
|
|
388
|
+
**`ScryptParams`**
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
interface ScryptParams
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**`PasswordsConfig`**
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
interface PasswordsConfig
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**`VerifyResult`**
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
interface VerifyResult
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**`Passwords`**
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
interface Passwords
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**`SignInConfig`**
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
interface SignInConfig
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**`SignInAttempt`**
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
interface SignInAttempt
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**`SignInResult`**
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
type SignInResult =
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**`SignIn`**
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
interface SignIn
|
|
434
|
+
```
|
|
435
|
+
|
|
380
436
|
**`MultiOrgConfig`** — Configuration for multi-org sessions — base sessions, signing keys, org-select token TTL.
|
|
381
437
|
|
|
382
438
|
```typescript
|
|
@@ -572,6 +628,10 @@ Base error class with code, statusCode, and suggestion fields.
|
|
|
572
628
|
|
|
573
629
|
409 — resource state conflict (duplicate, version mismatch).
|
|
574
630
|
|
|
631
|
+
### `errors.TooManyRequests`
|
|
632
|
+
|
|
633
|
+
429 — too many attempts; carries `retryAfterSeconds`, sent as a `Retry-After` header.
|
|
634
|
+
|
|
575
635
|
## lifecycle — Startup & Shutdown
|
|
576
636
|
|
|
577
637
|
Application lifecycle namespace — startup orchestration with hooks and timeouts.
|
|
@@ -703,7 +763,7 @@ Field builders for domain definitions — uuid(), text(), integer(), etc.
|
|
|
703
763
|
|
|
704
764
|
### `pipe.define`
|
|
705
765
|
|
|
706
|
-
Registers a domain definition with table, validators, and factory projections.
|
|
766
|
+
Registers a domain definition with table, validators, and factory projections. The `auditEntity` option names the `@touches` entity writes to this table are audited under (see `__flowStep`).
|
|
707
767
|
|
|
708
768
|
### `pipe.definitions`
|
|
709
769
|
|
|
@@ -1037,7 +1097,11 @@ Creates an Audit instance that writes audit records to a Postgres table.
|
|
|
1037
1097
|
|
|
1038
1098
|
### `audit.query`
|
|
1039
1099
|
|
|
1040
|
-
Queries the framework-managed `audit_record` table. Tenant-scoped via the active Flow.
|
|
1100
|
+
Queries the framework-managed `audit_record` table. Tenant-scoped via the active Flow. `{ entity, entityId }` returns one row's history from an index; build a composite key's `entityId` with `audit.entityId`.
|
|
1101
|
+
|
|
1102
|
+
### `audit.entityId`
|
|
1103
|
+
|
|
1104
|
+
The `entityId` filter text for a written table's row: the primary key's value as text, or for a composite key a compact JSON array of the key values as strings in key order (`["a","7"]`). Pass the table and a row (or just its key fields). Dates become ISO strings.
|
|
1041
1105
|
|
|
1042
1106
|
### `audit.chainHead`
|
|
1043
1107
|
|
|
@@ -1209,7 +1273,7 @@ interface ErrorResponse
|
|
|
1209
1273
|
interface PipeworkServer
|
|
1210
1274
|
```
|
|
1211
1275
|
|
|
1212
|
-
**`HttpRequest`** — Fastify request with pipework extensions — req.id (UUID), typed headers.
|
|
1276
|
+
**`HttpRequest`** — Fastify request with pipework extensions — req.id (UUID), typed headers, client address (`ip`, `ips`).
|
|
1213
1277
|
|
|
1214
1278
|
```typescript
|
|
1215
1279
|
interface HttpRequest
|
|
@@ -7,4 +7,8 @@ export type { CookieConfig, ResolvedCookieConfig } from './cookie.js';
|
|
|
7
7
|
export { resolveCookieConfig, buildSetCookieHeader, buildClearCookieHeader, parseCookieHeader } from './cookie.js';
|
|
8
8
|
export { createMultiOrgSessions } from './multi-org.js';
|
|
9
9
|
export type { MultiOrgConfig, MultiOrgSessions, ResolveLoginResult, AuthenticatedResult, OrgSelectResult, OrgMembership, OrgInfo, OrgMembershipDetail } from './multi-org.js';
|
|
10
|
+
export { createPasswords } from './passwords.js';
|
|
11
|
+
export type { Passwords, PasswordsConfig, ScryptParams, VerifyResult } from './passwords.js';
|
|
12
|
+
export { createSignIn } from './sign-in.js';
|
|
13
|
+
export type { SignIn, SignInConfig, SignInAttempt, SignInResult } from './sign-in.js';
|
|
10
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjI,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjI,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAC7K,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/auth/auth/index.js
CHANGED
|
@@ -2,4 +2,6 @@ export { runAuthChain } from './chain.js';
|
|
|
2
2
|
export { createSessions } from './sessions.js';
|
|
3
3
|
export { resolveCookieConfig, buildSetCookieHeader, buildClearCookieHeader, parseCookieHeader } from './cookie.js';
|
|
4
4
|
export { createMultiOrgSessions } from './multi-org.js';
|
|
5
|
+
export { createPasswords } from './passwords.js';
|
|
6
|
+
export { createSignIn } from './sign-in.js';
|
|
5
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAG9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAG9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -13,6 +13,10 @@ export interface MultiOrgConfig {
|
|
|
13
13
|
readonly orgSelectToken?: {
|
|
14
14
|
readonly expiresIn?: string;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Membership table name. Default `pipework_user_orgs`, whose definition ships with the `orgs: {}`
|
|
18
|
+
* blueprint flag. A custom name means the app owns that table's DDL (org_id uuid, same columns).
|
|
19
|
+
*/
|
|
16
20
|
readonly table?: string;
|
|
17
21
|
readonly resolveOrgNames?: (db: DB, orgIds: string[]) => Promise<Map<string, string>>;
|
|
18
22
|
}
|
|
@@ -72,6 +76,9 @@ export interface MultiOrgSessions {
|
|
|
72
76
|
}): Promise<void>;
|
|
73
77
|
checkMembership(db: DB, userId: string, orgId: string): Promise<OrgMembership | null>;
|
|
74
78
|
}
|
|
75
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* Creates a multi-org session manager with org selection flow and membership management.
|
|
81
|
+
* The default table comes from blueprint `orgs: {}`; org ids must be uuids.
|
|
82
|
+
*/
|
|
76
83
|
export declare function createMultiOrgSessions(config: MultiOrgConfig): MultiOrgSessions;
|
|
77
84
|
//# sourceMappingURL=multi-org.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-org.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/multi-org.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"multi-org.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/multi-org.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,11 @@ import { parseExpiry } from './parse-expiry.js';
|
|
|
3
3
|
import { sql } from '../../data/db/sql.js';
|
|
4
4
|
import { ForbiddenError, UnauthorizedError, ConflictError, NotFoundError } from '../../core/errors/index.js';
|
|
5
5
|
import { assertValidIdentifier } from '../../data/db/identifiers.js';
|
|
6
|
-
|
|
6
|
+
import { assertUuid } from './uuid.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a multi-org session manager with org selection flow and membership management.
|
|
9
|
+
* The default table comes from blueprint `orgs: {}`; org ids must be uuids.
|
|
10
|
+
*/
|
|
7
11
|
export function createMultiOrgSessions(config) {
|
|
8
12
|
const tableName = config.table ?? 'pipework_user_orgs';
|
|
9
13
|
assertValidIdentifier(tableName, 'multi-org membership table');
|
|
@@ -54,6 +58,7 @@ export function createMultiOrgSessions(config) {
|
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
async function requireMembership(db, userId, orgId) {
|
|
61
|
+
assertUuid(orgId, 'orgId');
|
|
57
62
|
const rows = await db.execute(sql `SELECT 1 FROM ${t} WHERE user_id = ${userId} AND org_id = ${orgId}`);
|
|
58
63
|
if (rows.length === 0) {
|
|
59
64
|
throw new ForbiddenError('You are not a member of this organization.');
|
|
@@ -108,6 +113,7 @@ export function createMultiOrgSessions(config) {
|
|
|
108
113
|
return { orgs };
|
|
109
114
|
}
|
|
110
115
|
async function addMember(db, params) {
|
|
116
|
+
assertUuid(params.orgId, 'orgId');
|
|
111
117
|
const role = params.role ?? null;
|
|
112
118
|
const addedBy = params.addedBy ?? null;
|
|
113
119
|
const rows = await db.execute(sql `INSERT INTO ${t} (user_id, org_id, role, added_by)
|
|
@@ -120,6 +126,7 @@ export function createMultiOrgSessions(config) {
|
|
|
120
126
|
return { id: rows[0]['id'] };
|
|
121
127
|
}
|
|
122
128
|
async function removeMember(db, params) {
|
|
129
|
+
assertUuid(params.orgId, 'orgId');
|
|
123
130
|
const rows = await db.execute(sql `DELETE FROM ${t} WHERE user_id = ${params.userId} AND org_id = ${params.orgId} RETURNING id`);
|
|
124
131
|
if (rows.length === 0) {
|
|
125
132
|
throw new NotFoundError('Membership');
|
|
@@ -127,6 +134,7 @@ export function createMultiOrgSessions(config) {
|
|
|
127
134
|
await config.sessions.bumpVersion(db, params.userId);
|
|
128
135
|
}
|
|
129
136
|
async function checkMembershipFn(db, userId, orgId) {
|
|
137
|
+
assertUuid(orgId, 'orgId');
|
|
130
138
|
const rows = await db.execute(sql `SELECT id, org_id, role, joined_at FROM ${t} WHERE user_id = ${userId} AND org_id = ${orgId}`);
|
|
131
139
|
if (rows.length === 0)
|
|
132
140
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-org.js","sourceRoot":"","sources":["../../../src/auth/auth/multi-org.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAE1C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC5G,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"multi-org.js","sourceRoot":"","sources":["../../../src/auth/auth/multi-org.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createSessions } from './sessions.js';
|
|
2
2
|
import { createMultiOrgSessions } from './multi-org.js';
|
|
3
|
+
import { createPasswords } from './passwords.js';
|
|
4
|
+
import { createSignIn } from './sign-in.js';
|
|
3
5
|
import { runAuthChain } from './chain.js';
|
|
4
6
|
import { resolveCookieConfig, parseCookieHeader, buildSetCookieHeader, buildClearCookieHeader } from './cookie.js';
|
|
5
7
|
/** Authentication namespace — session management, multi-org support, auth chain resolution. */
|
|
@@ -8,6 +10,10 @@ export declare const auth: {
|
|
|
8
10
|
createSessions: typeof createSessions;
|
|
9
11
|
/** Creates multi-org session management — org selection, switching, membership CRUD. */
|
|
10
12
|
createMultiOrg: typeof createMultiOrgSessions;
|
|
13
|
+
/** Hashes and verifies passwords with scrypt; reports when a stored hash needs rehashing. */
|
|
14
|
+
passwords: typeof createPasswords;
|
|
15
|
+
/** Guarded password sign-in that slows, then refuses, repeated failures per account and per client. */
|
|
16
|
+
signIn: typeof createSignIn;
|
|
11
17
|
/** Executes an auth chain (strategy pipeline) to resolve auth + tenant from a request. */
|
|
12
18
|
runChain: typeof runAuthChain;
|
|
13
19
|
/** Resolves CookieConfig with defaults for secure cookie-based token delivery. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,eAAO,MAAM,IAAI;IACf,gGAAgG;;IAEhG,wFAAwF;;IAExF,0FAA0F;;IAE1F,kFAAkF;;IAElF,0DAA0D;;IAE1D,4EAA4E;;IAE5E,iEAAiE;;CAElE,CAAA"}
|
|
1
|
+
{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,eAAO,MAAM,IAAI;IACf,gGAAgG;;IAEhG,wFAAwF;;IAExF,6FAA6F;;IAE7F,uGAAuG;;IAEvG,0FAA0F;;IAE1F,kFAAkF;;IAElF,0DAA0D;;IAE1D,4EAA4E;;IAE5E,iEAAiE;;CAElE,CAAA"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createSessions } from './sessions.js';
|
|
2
2
|
import { createMultiOrgSessions } from './multi-org.js';
|
|
3
|
+
import { createPasswords } from './passwords.js';
|
|
4
|
+
import { createSignIn } from './sign-in.js';
|
|
3
5
|
import { runAuthChain } from './chain.js';
|
|
4
6
|
import { resolveCookieConfig, parseCookieHeader, buildSetCookieHeader, buildClearCookieHeader } from './cookie.js';
|
|
5
7
|
/** Authentication namespace — session management, multi-org support, auth chain resolution. */
|
|
@@ -8,6 +10,10 @@ export const auth = {
|
|
|
8
10
|
createSessions,
|
|
9
11
|
/** Creates multi-org session management — org selection, switching, membership CRUD. */
|
|
10
12
|
createMultiOrg: createMultiOrgSessions,
|
|
13
|
+
/** Hashes and verifies passwords with scrypt; reports when a stored hash needs rehashing. */
|
|
14
|
+
passwords: createPasswords,
|
|
15
|
+
/** Guarded password sign-in that slows, then refuses, repeated failures per account and per client. */
|
|
16
|
+
signIn: createSignIn,
|
|
11
17
|
/** Executes an auth chain (strategy pipeline) to resolve auth + tenant from a request. */
|
|
12
18
|
runChain: runAuthChain,
|
|
13
19
|
/** Resolves CookieConfig with defaults for secure cookie-based token delivery. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,gGAAgG;IAChG,cAAc;IACd,wFAAwF;IACxF,cAAc,EAAE,sBAAsB;IACtC,0FAA0F;IAC1F,QAAQ,EAAE,YAAY;IACtB,kFAAkF;IAClF,aAAa,EAAE,mBAAmB;IAClC,0DAA0D;IAC1D,WAAW,EAAE,iBAAiB;IAC9B,4EAA4E;IAC5E,cAAc,EAAE,oBAAoB;IACpC,iEAAiE;IACjE,gBAAgB,EAAE,sBAAsB;CACzC,CAAA"}
|
|
1
|
+
{"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,gGAAgG;IAChG,cAAc;IACd,wFAAwF;IACxF,cAAc,EAAE,sBAAsB;IACtC,6FAA6F;IAC7F,SAAS,EAAE,eAAe;IAC1B,uGAAuG;IACvG,MAAM,EAAE,YAAY;IACpB,0FAA0F;IAC1F,QAAQ,EAAE,YAAY;IACtB,kFAAkF;IAClF,aAAa,EAAE,mBAAmB;IAClC,0DAA0D;IAC1D,WAAW,EAAE,iBAAiB;IAC9B,4EAA4E;IAC5E,cAAc,EAAE,oBAAoB;IACpC,iEAAiE;IACjE,gBAAgB,EAAE,sBAAsB;CACzC,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface ScryptParams {
|
|
2
|
+
/** log2 of the CPU/memory cost N. Default 15. */
|
|
3
|
+
readonly ln: number;
|
|
4
|
+
/** Block size. Default 8. */
|
|
5
|
+
readonly r: number;
|
|
6
|
+
/** Parallelism. Default 3. */
|
|
7
|
+
readonly p: number;
|
|
8
|
+
}
|
|
9
|
+
export interface PasswordsConfig {
|
|
10
|
+
readonly scrypt?: Partial<ScryptParams>;
|
|
11
|
+
}
|
|
12
|
+
export interface VerifyResult {
|
|
13
|
+
readonly ok: boolean;
|
|
14
|
+
/** True when the password matched but the stored hash used other parameters than the configured ones. */
|
|
15
|
+
readonly needsRehash: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface Passwords {
|
|
18
|
+
/** Returns a PHC string `$scrypt$ln=15,r=8,p=3$<salt>$<hash>` for the password. */
|
|
19
|
+
hash(password: string): Promise<string>;
|
|
20
|
+
/** Checks a password against a stored hash in constant time. A malformed stored hash is `ok: false`. */
|
|
21
|
+
verify(stored: string, password: string): Promise<VerifyResult>;
|
|
22
|
+
/** Spends the cost of a verify against a fixed dummy hash, for an account that does not exist. */
|
|
23
|
+
verifyNone(password: string): Promise<{
|
|
24
|
+
ok: false;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates the password hasher. Passwords are NFC-normalized and hashed with
|
|
29
|
+
* Node's scrypt (no dependency); there are no composition rules, and anything up
|
|
30
|
+
* to 4096 bytes of UTF-8 is accepted, so long passphrases and pasted passwords
|
|
31
|
+
* work. The hash records its own parameters, so raising `scrypt` later leaves old
|
|
32
|
+
* hashes verifiable and `verify` reports `needsRehash` for them.
|
|
33
|
+
*
|
|
34
|
+
* `verify` never throws on a bad stored string (it returns `ok: false` and logs),
|
|
35
|
+
* and `verifyNone` costs the same as a wrong password, so an unknown account is
|
|
36
|
+
* not distinguishable by timing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createPasswords(config?: PasswordsConfig): Passwords;
|
|
39
|
+
//# sourceMappingURL=passwords.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwords.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/passwords.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,6BAA6B;IAC7B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,8BAA8B;IAC9B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,yGAAyG;IACzG,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,mFAAmF;IACnF,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,wGAAwG;IACxG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC/D,kGAAkG;IAClG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,KAAK,CAAA;KAAE,CAAC,CAAA;CACrD;AAgCD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,MAAM,GAAE,eAAoB,GAAG,SAAS,CAoCvE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { scrypt, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { ValidationError } from '../../core/errors/index.js';
|
|
3
|
+
import { getBaseLogger } from '../../core/logging/index.js';
|
|
4
|
+
const DEFAULTS = { ln: 15, r: 8, p: 3 };
|
|
5
|
+
const KEY_LENGTH = 32;
|
|
6
|
+
const SALT_LENGTH = 16;
|
|
7
|
+
const MAX_PASSWORD_BYTES = 4096;
|
|
8
|
+
const STORED_RE = /^\$scrypt\$ln=(\d+),r=(\d+),p=(\d+)\$([A-Za-z0-9+/]+)\$([A-Za-z0-9+/]+)$/;
|
|
9
|
+
function derive(password, salt, params, length) {
|
|
10
|
+
const N = 2 ** params.ln;
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
scrypt(password, salt, length, { N, r: params.r, p: params.p, maxmem: 256 * N * params.r + (1 << 20) }, (err, key) => {
|
|
13
|
+
if (err !== null)
|
|
14
|
+
reject(err);
|
|
15
|
+
else
|
|
16
|
+
resolve(key);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function normalize(password) {
|
|
21
|
+
const normalized = password.normalize('NFC');
|
|
22
|
+
if (Buffer.byteLength(normalized, 'utf8') > MAX_PASSWORD_BYTES) {
|
|
23
|
+
throw new ValidationError({ password: [`must be at most ${MAX_PASSWORD_BYTES} bytes`] }, 'Password is too long.');
|
|
24
|
+
}
|
|
25
|
+
return normalized;
|
|
26
|
+
}
|
|
27
|
+
function validParams(p) {
|
|
28
|
+
return Number.isInteger(p.ln) && p.ln >= 1 && p.ln <= 22
|
|
29
|
+
&& Number.isInteger(p.r) && p.r >= 1 && p.r <= 32
|
|
30
|
+
&& Number.isInteger(p.p) && p.p >= 1 && p.p <= 16;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates the password hasher. Passwords are NFC-normalized and hashed with
|
|
34
|
+
* Node's scrypt (no dependency); there are no composition rules, and anything up
|
|
35
|
+
* to 4096 bytes of UTF-8 is accepted, so long passphrases and pasted passwords
|
|
36
|
+
* work. The hash records its own parameters, so raising `scrypt` later leaves old
|
|
37
|
+
* hashes verifiable and `verify` reports `needsRehash` for them.
|
|
38
|
+
*
|
|
39
|
+
* `verify` never throws on a bad stored string (it returns `ok: false` and logs),
|
|
40
|
+
* and `verifyNone` costs the same as a wrong password, so an unknown account is
|
|
41
|
+
* not distinguishable by timing.
|
|
42
|
+
*/
|
|
43
|
+
export function createPasswords(config = {}) {
|
|
44
|
+
const params = { ...DEFAULTS, ...config.scrypt };
|
|
45
|
+
if (!validParams(params)) {
|
|
46
|
+
throw new ValidationError('auth.passwords scrypt params must satisfy 1<=ln<=22, 1<=r<=32, 1<=p<=16.');
|
|
47
|
+
}
|
|
48
|
+
const encode = (b) => b.toString('base64').replace(/=+$/, '');
|
|
49
|
+
let dummy;
|
|
50
|
+
async function hash(password) {
|
|
51
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
52
|
+
const key = await derive(normalize(password), salt, params, KEY_LENGTH);
|
|
53
|
+
return `$scrypt$ln=${params.ln},r=${params.r},p=${params.p}$${encode(salt)}$${encode(key)}`;
|
|
54
|
+
}
|
|
55
|
+
async function verify(stored, password) {
|
|
56
|
+
const m = STORED_RE.exec(stored);
|
|
57
|
+
const storedParams = m === null ? null : { ln: Number(m[1]), r: Number(m[2]), p: Number(m[3]) };
|
|
58
|
+
if (m === null || storedParams === null || !validParams(storedParams)) {
|
|
59
|
+
getBaseLogger().error({ event: 'password hash malformed' }, 'stored password hash is malformed');
|
|
60
|
+
return { ok: false, needsRehash: false };
|
|
61
|
+
}
|
|
62
|
+
const salt = Buffer.from(m[4], 'base64');
|
|
63
|
+
const expected = Buffer.from(m[5], 'base64');
|
|
64
|
+
const key = await derive(normalize(password), salt, storedParams, expected.length);
|
|
65
|
+
const ok = key.length === expected.length && timingSafeEqual(key, expected);
|
|
66
|
+
const needsRehash = ok && (storedParams.ln !== params.ln || storedParams.r !== params.r || storedParams.p !== params.p);
|
|
67
|
+
return { ok, needsRehash };
|
|
68
|
+
}
|
|
69
|
+
async function verifyNone(password) {
|
|
70
|
+
dummy ??= hash(randomBytes(16).toString('hex'));
|
|
71
|
+
await verify(await dummy, password);
|
|
72
|
+
return { ok: false };
|
|
73
|
+
}
|
|
74
|
+
return { hash, verify, verifyNone };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=passwords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwords.js","sourceRoot":"","sources":["../../../src/auth/auth/passwords.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export declare const AUTH_TABLE_NAMES: ReadonlySet<string>;
|
|
2
|
+
export declare const refreshTokens: import("../../data/domain/types.js").DefinedTable<{
|
|
3
|
+
id: import("../../data/domain/types.js").FieldDescriptor<string, {
|
|
4
|
+
defaultRandom: true;
|
|
5
|
+
hasDefault: true;
|
|
6
|
+
} & {
|
|
7
|
+
primaryKey: true;
|
|
8
|
+
}> & import("../../data/domain/field.js").FieldModifiers<string, {
|
|
9
|
+
defaultRandom: true;
|
|
10
|
+
hasDefault: true;
|
|
11
|
+
} & {
|
|
12
|
+
primaryKey: true;
|
|
13
|
+
}>;
|
|
14
|
+
userId: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
|
|
15
|
+
tenantId: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
|
|
16
|
+
tokenHash: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
|
|
17
|
+
familyId: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
|
|
18
|
+
revokedAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
|
|
19
|
+
nullable: true;
|
|
20
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
|
|
21
|
+
nullable: true;
|
|
22
|
+
}>;
|
|
23
|
+
createdAt: import("../../data/domain/types.js").FieldDescriptor<Date, {
|
|
24
|
+
hasDefault: true;
|
|
25
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date, {
|
|
26
|
+
hasDefault: true;
|
|
27
|
+
}>;
|
|
28
|
+
expiresAt: import("../../data/domain/types.js").FieldDescriptor<Date, {}> & import("../../data/domain/field.js").FieldModifiers<Date, {}>;
|
|
29
|
+
}, "pipework_refresh_tokens">;
|
|
30
|
+
export declare const authVersions: import("../../data/domain/types.js").DefinedTable<{
|
|
31
|
+
userId: import("../../data/domain/types.js").FieldDescriptor<string, {
|
|
32
|
+
primaryKey: true;
|
|
33
|
+
}> & import("../../data/domain/field.js").FieldModifiers<string, {
|
|
34
|
+
primaryKey: true;
|
|
35
|
+
}>;
|
|
36
|
+
version: import("../../data/domain/types.js").FieldDescriptor<number, {
|
|
37
|
+
hasDefault: true;
|
|
38
|
+
}> & import("../../data/domain/field.js").FieldModifiers<number, {
|
|
39
|
+
hasDefault: true;
|
|
40
|
+
}>;
|
|
41
|
+
updatedAt: import("../../data/domain/types.js").FieldDescriptor<Date, {
|
|
42
|
+
hasDefault: true;
|
|
43
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date, {
|
|
44
|
+
hasDefault: true;
|
|
45
|
+
}>;
|
|
46
|
+
}, "pipework_auth_versions">;
|
|
47
|
+
export declare const userOrgs: import("../../data/domain/types.js").DefinedTable<{
|
|
48
|
+
id: import("../../data/domain/types.js").FieldDescriptor<string, {
|
|
49
|
+
defaultRandom: true;
|
|
50
|
+
hasDefault: true;
|
|
51
|
+
} & {
|
|
52
|
+
primaryKey: true;
|
|
53
|
+
}> & import("../../data/domain/field.js").FieldModifiers<string, {
|
|
54
|
+
defaultRandom: true;
|
|
55
|
+
hasDefault: true;
|
|
56
|
+
} & {
|
|
57
|
+
primaryKey: true;
|
|
58
|
+
}>;
|
|
59
|
+
userId: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
|
|
60
|
+
orgId: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
|
|
61
|
+
role: import("../../data/domain/types.js").FieldDescriptor<string | null, {
|
|
62
|
+
nullable: true;
|
|
63
|
+
}> & import("../../data/domain/field.js").FieldModifiers<string | null, {
|
|
64
|
+
nullable: true;
|
|
65
|
+
}>;
|
|
66
|
+
joinedAt: import("../../data/domain/types.js").FieldDescriptor<Date, {
|
|
67
|
+
hasDefault: true;
|
|
68
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date, {
|
|
69
|
+
hasDefault: true;
|
|
70
|
+
}>;
|
|
71
|
+
addedBy: import("../../data/domain/types.js").FieldDescriptor<string | null, {
|
|
72
|
+
nullable: true;
|
|
73
|
+
}> & import("../../data/domain/field.js").FieldModifiers<string | null, {
|
|
74
|
+
nullable: true;
|
|
75
|
+
}>;
|
|
76
|
+
}, "pipework_user_orgs">;
|
|
77
|
+
export declare const signinAttempts: import("../../data/domain/types.js").DefinedTable<{
|
|
78
|
+
key: import("../../data/domain/types.js").FieldDescriptor<string, {
|
|
79
|
+
primaryKey: true;
|
|
80
|
+
}> & import("../../data/domain/field.js").FieldModifiers<string, {
|
|
81
|
+
primaryKey: true;
|
|
82
|
+
}>;
|
|
83
|
+
failures: import("../../data/domain/types.js").FieldDescriptor<number, {
|
|
84
|
+
hasDefault: true;
|
|
85
|
+
}> & import("../../data/domain/field.js").FieldModifiers<number, {
|
|
86
|
+
hasDefault: true;
|
|
87
|
+
}>;
|
|
88
|
+
firstFailureAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
|
|
89
|
+
nullable: true;
|
|
90
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
|
|
91
|
+
nullable: true;
|
|
92
|
+
}>;
|
|
93
|
+
lastFailureAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
|
|
94
|
+
nullable: true;
|
|
95
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
|
|
96
|
+
nullable: true;
|
|
97
|
+
}>;
|
|
98
|
+
lockedUntil: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
|
|
99
|
+
nullable: true;
|
|
100
|
+
}> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
|
|
101
|
+
nullable: true;
|
|
102
|
+
}>;
|
|
103
|
+
}, "pipework_signin_attempts">;
|
|
104
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/schema.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAE/C,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAexB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;4BAIvB,CAAA;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAanB,CAAA;AAIF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;8BAMzB,CAAA"}
|