@boopkit/cap-users 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.
@@ -9,12 +9,57 @@ export interface IdentityServiceOptions {
9
9
  export interface IdentityQueryOptions {
10
10
  includeEnded?: boolean;
11
11
  }
12
+ /** Rows per page when a key-prefix scan is not told otherwise. */
13
+ export declare const IDENTITY_PREFIX_PAGE_SIZE = 100;
14
+ /** The most a single page of a key-prefix scan will return, however asked. */
15
+ export declare const IDENTITY_PREFIX_MAX_PAGE_SIZE = 500;
16
+ /** Options for the key-prefix scan. */
17
+ export interface IdentityPrefixQueryOptions extends IdentityQueryOptions {
18
+ /**
19
+ * Rows in this page. Defaults to `IDENTITY_PREFIX_PAGE_SIZE` and is clamped
20
+ * to `IDENTITY_PREFIX_MAX_PAGE_SIZE`, so a caller cannot turn the scan into
21
+ * the whole-table read it exists to avoid.
22
+ */
23
+ limit?: number;
24
+ /** Exclusive cursor — the previous page's `nextCursor`. */
25
+ after?: number;
26
+ }
27
+ /** One page of a key-prefix scan. */
28
+ export interface IdentityPrefixPage {
29
+ identities: UserIdentity[];
30
+ /**
31
+ * Feed back as `after` to continue. `null` when this page ended the scan.
32
+ *
33
+ * A full page always answers with a cursor, even when it happened to be the
34
+ * last one, so the caller's final request is an empty page rather than a
35
+ * count the query cannot know without a second read.
36
+ */
37
+ nextCursor: number | null;
38
+ }
12
39
  /** The service object returned by createIdentityService. */
13
40
  export interface IdentityService {
14
41
  create(userId: number, domain: string, key: string): Promise<UserIdentity>;
15
42
  findByDomainAndKey(domain: string, key: string): Promise<UserIdentity | null>;
16
43
  findByUserAndDomain(userId: number, domain: string): Promise<UserIdentity | null>;
17
44
  findAllByUser(userId: number, opts?: IdentityQueryOptions): Promise<UserIdentity[]>;
45
+ /**
46
+ * One page of the rows in `domain` whose key starts with `keyPrefix`, in id
47
+ * order, for any user.
48
+ *
49
+ * This is the only read here that is not bounded by a user id, and it exists
50
+ * for one job: a credential domain whose keys are `"<issuer>|<secret hash>"`
51
+ * — cap-oauth-server's token rows — needs to enumerate everybody one issuer
52
+ * ever reached, so that a compromised client can be retired without the
53
+ * operator already knowing which accounts to sweep.
54
+ *
55
+ * Both narrowings are load-bearing rather than conveniences. The **domain is
56
+ * required** so the scan cannot wander into `email` or `api-key` rows, and an
57
+ * **empty prefix is refused** because it would walk a whole domain — which is
58
+ * the read this method is shaped to make unnecessary. Left-anchored, the
59
+ * comparison is a seek on the `(domain, key)` unique index rather than a
60
+ * table scan, which is the whole reason the key format puts the issuer first.
61
+ */
62
+ findAllByDomainAndKeyPrefix(domain: string, keyPrefix: string, opts?: IdentityPrefixQueryOptions): Promise<IdentityPrefixPage>;
18
63
  update(domain: string, key: string, newUserId: number): Promise<UserIdentity>;
19
64
  endDate(domain: string, key: string): Promise<UserIdentity>;
20
65
  }
@@ -31,6 +76,10 @@ interface IdentityDelegate {
31
76
  }): Promise<Record<string, unknown> | null>;
32
77
  findMany(args: {
33
78
  where: Record<string, unknown>;
79
+ orderBy?: {
80
+ id?: 'asc' | 'desc';
81
+ };
82
+ take?: number;
34
83
  }): Promise<Record<string, unknown>[]>;
35
84
  update(args: {
36
85
  where: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"identity-service.d.ts","sourceRoot":"","sources":["../src/identity-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,kDAAkD;AAClD,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,SAAS,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;CACxC;AAED,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3E,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9E,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClF,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACpF,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9E,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC7D;AAED,kEAAkE;AAClE,UAAU,gBAAgB;IACxB,MAAM,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClF,UAAU,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9F,SAAS,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7F,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvF,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnH;AAkCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,eAAe,CA8DjB"}
1
+ {"version":3,"file":"identity-service.d.ts","sourceRoot":"","sources":["../src/identity-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,kDAAkD;AAClD,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,SAAS,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;CACxC;AAED,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,uCAAuC;AACvC,MAAM,WAAW,0BAA2B,SAAQ,oBAAoB;IACtE;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qCAAqC;AACrC,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3E,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9E,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClF,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACpF;;;;;;;;;;;;;;;;OAgBG;IACH,2BAA2B,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,0BAA0B,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9E,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC7D;AAED,kEAAkE;AAClE,UAAU,gBAAgB;IACxB,MAAM,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClF,UAAU,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9F,SAAS,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7F,QAAQ,CAAC,IAAI,EAAE;QACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,CAAC,EAAE;YAAE,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC;QAClC,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnH;AAkCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,eAAe,CA2GjB"}
@@ -1,7 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IDENTITY_PREFIX_MAX_PAGE_SIZE = exports.IDENTITY_PREFIX_PAGE_SIZE = void 0;
3
4
  exports.createIdentityService = createIdentityService;
4
5
  const types_js_1 = require("./types.js");
6
+ /** Rows per page when a key-prefix scan is not told otherwise. */
7
+ exports.IDENTITY_PREFIX_PAGE_SIZE = 100;
8
+ /** The most a single page of a key-prefix scan will return, however asked. */
9
+ exports.IDENTITY_PREFIX_MAX_PAGE_SIZE = 500;
5
10
  function toIdentity(row) {
6
11
  const endedAt = row.endedAt;
7
12
  return {
@@ -75,6 +80,35 @@ function createIdentityService(model, options) {
75
80
  const rows = await model.findMany({ where });
76
81
  return rows.map(toIdentity);
77
82
  },
83
+ async findAllByDomainAndKeyPrefix(domain, keyPrefix, opts) {
84
+ if (!domain) {
85
+ throw new TypeError('Unable to scan identities by key prefix: no domain was given. ' +
86
+ 'Pass the identity domain to scan, such as "oauth-access".');
87
+ }
88
+ if (!keyPrefix) {
89
+ throw new TypeError(`Unable to scan identities by key prefix: the prefix was empty, which would read every "${domain}" row. ` +
90
+ 'Pass the prefix to match, or use findAllByUser for one user\'s identities.');
91
+ }
92
+ const limit = Math.min(Math.max(1, Math.trunc(opts?.limit ?? exports.IDENTITY_PREFIX_PAGE_SIZE)), exports.IDENTITY_PREFIX_MAX_PAGE_SIZE);
93
+ const where = {
94
+ domain,
95
+ key: { startsWith: normalizeKey(domain, keyPrefix) },
96
+ };
97
+ if (!opts?.includeEnded) {
98
+ where.endedAt = null;
99
+ }
100
+ // The cursor is the row id rather than an offset: pages are stable under
101
+ // rows arriving mid-scan, which for a token table is every request.
102
+ if (opts?.after != null) {
103
+ where.id = { gt: opts.after };
104
+ }
105
+ const rows = await model.findMany({ where, orderBy: { id: 'asc' }, take: limit });
106
+ const identities = rows.map(toIdentity);
107
+ return {
108
+ identities,
109
+ nextCursor: identities.length === limit ? identities[identities.length - 1].id : null,
110
+ };
111
+ },
78
112
  async update(domain, key, newUserId) {
79
113
  const row = await model.update({
80
114
  where: domainKeyWhere(domain, normalizeKey(domain, key)),
@@ -1 +1 @@
1
- {"version":3,"file":"identity-service.js","sourceRoot":"","sources":["../src/identity-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"identity-service.js","sourceRoot":"","sources":["../src/identity-service.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,13 +9,14 @@ export type { BaseUserInfo, User, UserIdentity, UserProfile, CredentialEntry, Us
9
9
  export { createUserService } from './user-service.js';
10
10
  export type { UserService, UserServiceOptions } from './user-service.js';
11
11
  export { createIdentityService } from './identity-service.js';
12
- export type { IdentityService, IdentityServiceOptions, IdentityQueryOptions } from './identity-service.js';
12
+ export { IDENTITY_PREFIX_PAGE_SIZE, IDENTITY_PREFIX_MAX_PAGE_SIZE, } from './identity-service.js';
13
+ export type { IdentityService, IdentityServiceOptions, IdentityQueryOptions, IdentityPrefixQueryOptions, IdentityPrefixPage, } from './identity-service.js';
13
14
  export { createUserPropertyService } from './user-property-service.js';
14
15
  export type { UserPropertyService, UserPropertyServiceOptions } from './user-property-service.js';
15
- export { createAuthService, AuthValidationError, AuthError, generateToken, hashToken } from './auth-service.js';
16
+ export { createAuthService, AuthValidationError, AuthError, generateToken, hashToken, isHashedToken } from './auth-service.js';
16
17
  export type { AuthService, AuthServiceDeps, AuthServiceOptions, AddAuthMethodOptions, SignupInput, SignupResult, LoginResult, VerifyEmailResult, } from './auth-service.js';
17
- export { createAuthMiddleware } from './auth-middleware.js';
18
- export type { AuthMiddleware, AuthMiddlewareDeps, AuthMiddlewareOptions, AuthLocals, } from './auth-middleware.js';
18
+ export { createAuthMiddleware, createBearerMiddleware } from './auth-middleware.js';
19
+ export type { AuthMiddleware, AuthMiddlewareDeps, AuthMiddlewareOptions, BearerMiddlewareOptions, AuthLocals, } from './auth-middleware.js';
19
20
  export { createAccountService } from './account-service.js';
20
21
  export type { AccountService, AccountServiceOptions } from './account-service.js';
21
22
  export { createAccountPropertyService } from './account-property-service.js';
@@ -24,4 +25,7 @@ export { createAccountManagementService, AccountManagementError } from './accoun
24
25
  export type { AccountManagementService, AccountManagementServiceDeps, AccountManagementServiceOptions, ProvisionAccountInput, ProvisionAccountResult, TeamMember, } from './account-management-service.js';
25
26
  export { createTeamInvitationService, TeamInvitationError, DEFAULT_INVITATION_TTL_MS, MAX_PENDING_INVITATIONS, MAX_RESENDS, } from './team-invitation-service.js';
26
27
  export type { TeamInvitation, TeamInvitationsPropertyInfo, TeamInvitationService, TeamInvitationServiceDeps, TeamInvitationServiceOptions, AccountUserRole, } from './team-invitation-service.js';
28
+ export { AUTHORIZATION_HASHED_INFO_SCHEMA, TEAM_INVITATIONS_HASHED_INFO_SCHEMA, } from './info-schema-tags.js';
29
+ export { migrateCredentialStore, rehashAuthorizationGrants, authorizationStore, rehashTeamInvitations, teamInvitationsStore, } from './credential-migration.js';
30
+ export type { MigrationDelegate, CredentialStore, RehashResult, MigrationReport, } from './credential-migration.js';
27
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC/E,YAAY,EACV,YAAY,EACZ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,OAAO,EACP,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE3G,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAElG,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChH,YAAY,EACV,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,YAAY,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAE3G,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzG,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,+BAA+B,EAC/B,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,GACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,WAAW,GACZ,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,cAAc,EACd,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,eAAe,GAChB,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC/E,YAAY,EACV,YAAY,EACZ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,OAAO,EACP,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAElG,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC/H,YAAY,EACV,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACpF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,YAAY,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAE3G,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzG,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,+BAA+B,EAC/B,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,GACX,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,WAAW,GACZ,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,cAAc,EACd,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,eAAe,GAChB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,gCAAgC,EAChC,mCAAmC,GACpC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,eAAe,GAChB,MAAM,2BAA2B,CAAC"}
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * composing on top of @boopkit/cap-services primitives.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.MAX_RESENDS = exports.MAX_PENDING_INVITATIONS = exports.DEFAULT_INVITATION_TTL_MS = exports.TeamInvitationError = exports.createTeamInvitationService = exports.AccountManagementError = exports.createAccountManagementService = exports.createAccountPropertyService = exports.createAccountService = exports.createAuthMiddleware = exports.hashToken = exports.generateToken = exports.AuthError = exports.AuthValidationError = exports.createAuthService = exports.createUserPropertyService = exports.createIdentityService = exports.createUserService = exports.DuplicateAccountUserError = exports.DuplicateIdentityError = void 0;
9
+ exports.teamInvitationsStore = exports.rehashTeamInvitations = exports.authorizationStore = exports.rehashAuthorizationGrants = exports.migrateCredentialStore = exports.TEAM_INVITATIONS_HASHED_INFO_SCHEMA = exports.AUTHORIZATION_HASHED_INFO_SCHEMA = exports.MAX_RESENDS = exports.MAX_PENDING_INVITATIONS = exports.DEFAULT_INVITATION_TTL_MS = exports.TeamInvitationError = exports.createTeamInvitationService = exports.AccountManagementError = exports.createAccountManagementService = exports.createAccountPropertyService = exports.createAccountService = exports.createBearerMiddleware = exports.createAuthMiddleware = exports.isHashedToken = exports.hashToken = exports.generateToken = exports.AuthError = exports.AuthValidationError = exports.createAuthService = exports.createUserPropertyService = exports.IDENTITY_PREFIX_MAX_PAGE_SIZE = exports.IDENTITY_PREFIX_PAGE_SIZE = exports.createIdentityService = exports.createUserService = exports.DuplicateAccountUserError = exports.DuplicateIdentityError = void 0;
10
10
  var types_js_1 = require("./types.js");
11
11
  Object.defineProperty(exports, "DuplicateIdentityError", { enumerable: true, get: function () { return types_js_1.DuplicateIdentityError; } });
12
12
  Object.defineProperty(exports, "DuplicateAccountUserError", { enumerable: true, get: function () { return types_js_1.DuplicateAccountUserError; } });
@@ -14,6 +14,9 @@ var user_service_js_1 = require("./user-service.js");
14
14
  Object.defineProperty(exports, "createUserService", { enumerable: true, get: function () { return user_service_js_1.createUserService; } });
15
15
  var identity_service_js_1 = require("./identity-service.js");
16
16
  Object.defineProperty(exports, "createIdentityService", { enumerable: true, get: function () { return identity_service_js_1.createIdentityService; } });
17
+ var identity_service_js_2 = require("./identity-service.js");
18
+ Object.defineProperty(exports, "IDENTITY_PREFIX_PAGE_SIZE", { enumerable: true, get: function () { return identity_service_js_2.IDENTITY_PREFIX_PAGE_SIZE; } });
19
+ Object.defineProperty(exports, "IDENTITY_PREFIX_MAX_PAGE_SIZE", { enumerable: true, get: function () { return identity_service_js_2.IDENTITY_PREFIX_MAX_PAGE_SIZE; } });
17
20
  var user_property_service_js_1 = require("./user-property-service.js");
18
21
  Object.defineProperty(exports, "createUserPropertyService", { enumerable: true, get: function () { return user_property_service_js_1.createUserPropertyService; } });
19
22
  var auth_service_js_1 = require("./auth-service.js");
@@ -22,8 +25,10 @@ Object.defineProperty(exports, "AuthValidationError", { enumerable: true, get: f
22
25
  Object.defineProperty(exports, "AuthError", { enumerable: true, get: function () { return auth_service_js_1.AuthError; } });
23
26
  Object.defineProperty(exports, "generateToken", { enumerable: true, get: function () { return auth_service_js_1.generateToken; } });
24
27
  Object.defineProperty(exports, "hashToken", { enumerable: true, get: function () { return auth_service_js_1.hashToken; } });
28
+ Object.defineProperty(exports, "isHashedToken", { enumerable: true, get: function () { return auth_service_js_1.isHashedToken; } });
25
29
  var auth_middleware_js_1 = require("./auth-middleware.js");
26
30
  Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return auth_middleware_js_1.createAuthMiddleware; } });
31
+ Object.defineProperty(exports, "createBearerMiddleware", { enumerable: true, get: function () { return auth_middleware_js_1.createBearerMiddleware; } });
27
32
  var account_service_js_1 = require("./account-service.js");
28
33
  Object.defineProperty(exports, "createAccountService", { enumerable: true, get: function () { return account_service_js_1.createAccountService; } });
29
34
  var account_property_service_js_1 = require("./account-property-service.js");
@@ -37,4 +42,13 @@ Object.defineProperty(exports, "TeamInvitationError", { enumerable: true, get: f
37
42
  Object.defineProperty(exports, "DEFAULT_INVITATION_TTL_MS", { enumerable: true, get: function () { return team_invitation_service_js_1.DEFAULT_INVITATION_TTL_MS; } });
38
43
  Object.defineProperty(exports, "MAX_PENDING_INVITATIONS", { enumerable: true, get: function () { return team_invitation_service_js_1.MAX_PENDING_INVITATIONS; } });
39
44
  Object.defineProperty(exports, "MAX_RESENDS", { enumerable: true, get: function () { return team_invitation_service_js_1.MAX_RESENDS; } });
45
+ var info_schema_tags_js_1 = require("./info-schema-tags.js");
46
+ Object.defineProperty(exports, "AUTHORIZATION_HASHED_INFO_SCHEMA", { enumerable: true, get: function () { return info_schema_tags_js_1.AUTHORIZATION_HASHED_INFO_SCHEMA; } });
47
+ Object.defineProperty(exports, "TEAM_INVITATIONS_HASHED_INFO_SCHEMA", { enumerable: true, get: function () { return info_schema_tags_js_1.TEAM_INVITATIONS_HASHED_INFO_SCHEMA; } });
48
+ var credential_migration_js_1 = require("./credential-migration.js");
49
+ Object.defineProperty(exports, "migrateCredentialStore", { enumerable: true, get: function () { return credential_migration_js_1.migrateCredentialStore; } });
50
+ Object.defineProperty(exports, "rehashAuthorizationGrants", { enumerable: true, get: function () { return credential_migration_js_1.rehashAuthorizationGrants; } });
51
+ Object.defineProperty(exports, "authorizationStore", { enumerable: true, get: function () { return credential_migration_js_1.authorizationStore; } });
52
+ Object.defineProperty(exports, "rehashTeamInvitations", { enumerable: true, get: function () { return credential_migration_js_1.rehashTeamInvitations; } });
53
+ Object.defineProperty(exports, "teamInvitationsStore", { enumerable: true, get: function () { return credential_migration_js_1.teamInvitationsStore; } });
40
54
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,uCAA+E;AAAtE,kHAAA,sBAAsB,OAAA;AAAE,qHAAA,yBAAyB,OAAA;AAmB1D,qDAAsD;AAA7C,oHAAA,iBAAiB,OAAA;AAG1B,6DAA8D;AAArD,4HAAA,qBAAqB,OAAA;AAG9B,uEAAuE;AAA9D,qIAAA,yBAAyB,OAAA;AAGlC,qDAAgH;AAAvG,oHAAA,iBAAiB,OAAA;AAAE,sHAAA,mBAAmB,OAAA;AAAE,4GAAA,SAAS,OAAA;AAAE,gHAAA,aAAa,OAAA;AAAE,4GAAA,SAAS,OAAA;AAYpF,2DAA4D;AAAnD,0HAAA,oBAAoB,OAAA;AAQ7B,2DAA4D;AAAnD,0HAAA,oBAAoB,OAAA;AAG7B,6EAA6E;AAApE,2IAAA,4BAA4B,OAAA;AAGrC,iFAAyG;AAAhG,+IAAA,8BAA8B,OAAA;AAAE,uIAAA,sBAAsB,OAAA;AAU/D,2EAMsC;AALpC,yIAAA,2BAA2B,OAAA;AAC3B,iIAAA,mBAAmB,OAAA;AACnB,uIAAA,yBAAyB,OAAA;AACzB,qIAAA,uBAAuB,OAAA;AACvB,yHAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,uCAA+E;AAAtE,kHAAA,sBAAsB,OAAA;AAAE,qHAAA,yBAAyB,OAAA;AAmB1D,qDAAsD;AAA7C,oHAAA,iBAAiB,OAAA;AAG1B,6DAA8D;AAArD,4HAAA,qBAAqB,OAAA;AAC9B,6DAG+B;AAF7B,gIAAA,yBAAyB,OAAA;AACzB,oIAAA,6BAA6B,OAAA;AAU/B,uEAAuE;AAA9D,qIAAA,yBAAyB,OAAA;AAGlC,qDAA+H;AAAtH,oHAAA,iBAAiB,OAAA;AAAE,sHAAA,mBAAmB,OAAA;AAAE,4GAAA,SAAS,OAAA;AAAE,gHAAA,aAAa,OAAA;AAAE,4GAAA,SAAS,OAAA;AAAE,gHAAA,aAAa,OAAA;AAYnG,2DAAoF;AAA3E,0HAAA,oBAAoB,OAAA;AAAE,4HAAA,sBAAsB,OAAA;AASrD,2DAA4D;AAAnD,0HAAA,oBAAoB,OAAA;AAG7B,6EAA6E;AAApE,2IAAA,4BAA4B,OAAA;AAGrC,iFAAyG;AAAhG,+IAAA,8BAA8B,OAAA;AAAE,uIAAA,sBAAsB,OAAA;AAU/D,2EAMsC;AALpC,yIAAA,2BAA2B,OAAA;AAC3B,iIAAA,mBAAmB,OAAA;AACnB,uIAAA,yBAAyB,OAAA;AACzB,qIAAA,uBAAuB,OAAA;AACvB,yHAAA,WAAW,OAAA;AAWb,6DAG+B;AAF7B,uIAAA,gCAAgC,OAAA;AAChC,0IAAA,mCAAmC,OAAA;AAGrC,qEAMmC;AALjC,iIAAA,sBAAsB,OAAA;AACtB,oIAAA,yBAAyB,OAAA;AACzB,6HAAA,kBAAkB,OAAA;AAClB,gIAAA,qBAAqB,OAAA;AACrB,+HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * info_schema tags that mark a property payload as written by the
3
+ * credential-hashing library (boop-j8xc epic).
4
+ *
5
+ * Both property tables carry an `info_schema` column that versions the payload
6
+ * shape. For most properties it stays `''`. The two properties that once stored
7
+ * a raw, redeemable credential get a distinct tag the moment their values are
8
+ * hashed — stamped by the fixed library on every new write and by the migration
9
+ * tool on every row it rewrites (boop-j8xc.2 and boop-j8xc.3).
10
+ *
11
+ * The `boop status` data probe uses these tags as a fast, exact migration
12
+ * signal: a row missing the tag predates the fix and may hold a cleartext
13
+ * credential, so the probe needs no JSON parsing — one column comparison with
14
+ * an early exit. Keep each literal in sync with the matching probe query in
15
+ * `capability.json`.
16
+ */
17
+ /** Stamped on the `authorization` user-property once its grants store hashed identity keys. */
18
+ export declare const AUTHORIZATION_HASHED_INFO_SCHEMA = "authorization-hashed-01";
19
+ /** Stamped on the `team_invitations` account-property once its tokens are stored hashed. */
20
+ export declare const TEAM_INVITATIONS_HASHED_INFO_SCHEMA = "team-invitations-hashed-01";
21
+ //# sourceMappingURL=info-schema-tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info-schema-tags.d.ts","sourceRoot":"","sources":["../src/info-schema-tags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,+FAA+F;AAC/F,eAAO,MAAM,gCAAgC,4BAA4B,CAAC;AAE1E,4FAA4F;AAC5F,eAAO,MAAM,mCAAmC,+BAA+B,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * info_schema tags that mark a property payload as written by the
4
+ * credential-hashing library (boop-j8xc epic).
5
+ *
6
+ * Both property tables carry an `info_schema` column that versions the payload
7
+ * shape. For most properties it stays `''`. The two properties that once stored
8
+ * a raw, redeemable credential get a distinct tag the moment their values are
9
+ * hashed — stamped by the fixed library on every new write and by the migration
10
+ * tool on every row it rewrites (boop-j8xc.2 and boop-j8xc.3).
11
+ *
12
+ * The `boop status` data probe uses these tags as a fast, exact migration
13
+ * signal: a row missing the tag predates the fix and may hold a cleartext
14
+ * credential, so the probe needs no JSON parsing — one column comparison with
15
+ * an early exit. Keep each literal in sync with the matching probe query in
16
+ * `capability.json`.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.TEAM_INVITATIONS_HASHED_INFO_SCHEMA = exports.AUTHORIZATION_HASHED_INFO_SCHEMA = void 0;
20
+ /** Stamped on the `authorization` user-property once its grants store hashed identity keys. */
21
+ exports.AUTHORIZATION_HASHED_INFO_SCHEMA = 'authorization-hashed-01';
22
+ /** Stamped on the `team_invitations` account-property once its tokens are stored hashed. */
23
+ exports.TEAM_INVITATIONS_HASHED_INFO_SCHEMA = 'team-invitations-hashed-01';
24
+ //# sourceMappingURL=info-schema-tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info-schema-tags.js","sourceRoot":"","sources":["../src/info-schema-tags.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,+FAA+F;AAClF,QAAA,gCAAgC,GAAG,yBAAyB,CAAC;AAE1E,4FAA4F;AAC/E,QAAA,mCAAmC,GAAG,4BAA4B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"team-invitation-service.d.ts","sourceRoot":"","sources":["../src/team-invitation-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"team-invitation-service.d.ts","sourceRoot":"","sources":["../src/team-invitation-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQ7D,eAAO,MAAM,yBAAyB,QAA0B,CAAC;AACjE,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,YAAY,QAA2B,CAAC;AAsCrD,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;IACzD,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAID,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAID,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7D,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACpE,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC1C,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACnF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACnF;;;;OAIG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACrG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAC/E;AAID,MAAM,WAAW,yBAAyB;IACxC,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,cAAc,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAChD,eAAe,EAAE,eAAe,CAAC;CAClC;AAID,MAAM,WAAW,4BAA4B;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,yBAAyB,EAC/B,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB,CA0QvB"}
@@ -3,7 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TeamInvitationError = exports.PRUNE_AGE_MS = exports.PRUNE_THRESHOLD = exports.MAX_RESENDS = exports.MAX_PENDING_INVITATIONS = exports.DEFAULT_INVITATION_TTL_MS = void 0;
4
4
  exports.createTeamInvitationService = createTeamInvitationService;
5
5
  const auth_service_js_1 = require("./auth-service.js");
6
+ const info_schema_tags_js_1 = require("./info-schema-tags.js");
6
7
  const cap_services_1 = require("@boopkit/cap-services");
8
+ const logger_1 = require("@boopkit/logger");
9
+ const logger = (0, logger_1.createLogger)('users', 'invitations');
7
10
  // ---------- Constants ----------
8
11
  exports.DEFAULT_INVITATION_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
9
12
  exports.MAX_PENDING_INVITATIONS = 20;
@@ -11,9 +14,35 @@ exports.MAX_RESENDS = 3;
11
14
  exports.PRUNE_THRESHOLD = 100;
12
15
  exports.PRUNE_AGE_MS = 90 * 24 * 60 * 60 * 1000; // 90 days
13
16
  const PROPERTY = 'team_invitations';
14
- const SCHEMA = 'team-invitations-01';
15
17
  const MAX_CONCURRENCY_RETRIES = 3;
16
18
  const TERMINAL_STATUSES = new Set(['accepted', 'cancelled', 'expired']);
19
+ // An invitation token is a bearer credential: presenting it joins the account at
20
+ // the role the invitation grants. The stored `token` is therefore hashed, exactly
21
+ // as session cookies and API keys are — the raw value is emailed to the invitee
22
+ // once and never persisted. The read path hashes the presented token before
23
+ // comparing. Rows written before this fix stored the RAW token, and boop cannot
24
+ // know whether a downstream has run the migration, so the read tolerates BOTH
25
+ // forms permanently. The raw branch logs once per process to nudge an operator
26
+ // toward the migration; it goes quiet on its own once the data is hashed.
27
+ let warnedRawInvitation = false;
28
+ /**
29
+ * Does a stored invitation `storedToken` correspond to the raw `rawToken` a
30
+ * caller presented? Matches the hashed form (new writes and migrated rows) and
31
+ * the raw form (pre-hash rows). The raw branch warns once per process. Mirrors
32
+ * `grantMatchesIdentityKey` in auth-service, for the same reason.
33
+ */
34
+ function invitationMatchesToken(storedToken, rawToken) {
35
+ if (storedToken === (0, auth_service_js_1.hashToken)(rawToken))
36
+ return true;
37
+ if (storedToken === rawToken && !(0, auth_service_js_1.isHashedToken)(storedToken)) {
38
+ if (!warnedRawInvitation) {
39
+ warnedRawInvitation = true;
40
+ logger.warn('invitation matched a raw (pre-hash) token; run the credential-hashing migration to rehash it');
41
+ }
42
+ return true;
43
+ }
44
+ return false;
45
+ }
17
46
  // ---------- Errors ----------
18
47
  class TeamInvitationError extends Error {
19
48
  constructor(message) {
@@ -57,7 +86,7 @@ function createTeamInvitationService(deps, options) {
57
86
  }
58
87
  async function saveInvitations(accountId, invitations, expectedRevision) {
59
88
  pruneTerminalInvitations(invitations);
60
- await accountPropertyService.put(accountId, PROPERTY, { invitations }, { infoSchema: SCHEMA, expectedRevision });
89
+ await accountPropertyService.put(accountId, PROPERTY, { invitations }, { infoSchema: info_schema_tags_js_1.TEAM_INVITATIONS_HASHED_INFO_SCHEMA, expectedRevision });
61
90
  }
62
91
  /**
63
92
  * Retry a read-modify-write operation on StaleEntityError (optimistic concurrency conflict).
@@ -129,9 +158,11 @@ function createTeamInvitationService(deps, options) {
129
158
  throw new TeamInvitationError(`Maximum of ${maxPending} pending invitations reached`);
130
159
  }
131
160
  const now = new Date();
161
+ // The raw token is emailed to the invitee; only its hash is persisted.
162
+ const rawToken = (0, auth_service_js_1.generateToken)();
132
163
  const invitation = {
133
164
  id: (0, auth_service_js_1.generateToken)(),
134
- token: (0, auth_service_js_1.generateToken)(),
165
+ token: (0, auth_service_js_1.hashToken)(rawToken),
135
166
  email: normalizedEmail,
136
167
  role,
137
168
  status: 'pending',
@@ -143,7 +174,8 @@ function createTeamInvitationService(deps, options) {
143
174
  };
144
175
  snapshot.invitations.push(invitation);
145
176
  await saveInvitations(accountId, snapshot.invitations, snapshot.revision);
146
- return invitation;
177
+ // Hand the caller the RAW token to email; the stored record keeps only the hash.
178
+ return { ...invitation, token: rawToken };
147
179
  });
148
180
  }
149
181
  async function cancelInvitation(accountId, invitationId) {
@@ -171,11 +203,13 @@ function createTeamInvitationService(deps, options) {
171
203
  if (inv.resendCount >= maxResends) {
172
204
  throw new TeamInvitationError(`Maximum of ${maxResends} resends reached for this invitation`);
173
205
  }
174
- inv.token = (0, auth_service_js_1.generateToken)();
206
+ // Mint a fresh raw token, persist only its hash, and email the raw value.
207
+ const rawToken = (0, auth_service_js_1.generateToken)();
208
+ inv.token = (0, auth_service_js_1.hashToken)(rawToken);
175
209
  inv.expiresAt = new Date(Date.now() + invitationTtl).toISOString();
176
210
  inv.resendCount += 1;
177
211
  await saveInvitations(accountId, snapshot.invitations, snapshot.revision);
178
- return inv;
212
+ return { ...inv, token: rawToken };
179
213
  });
180
214
  }
181
215
  /**
@@ -188,7 +222,7 @@ function createTeamInvitationService(deps, options) {
188
222
  const snapshot = await loadInvitations(accountId);
189
223
  applyLazyExpiry(snapshot.invitations);
190
224
  const now = new Date().toISOString();
191
- const inv = snapshot.invitations.find((i) => i.token === token && i.status === 'pending');
225
+ const inv = snapshot.invitations.find((i) => i.status === 'pending' && invitationMatchesToken(i.token, token));
192
226
  if (!inv) {
193
227
  throw new TeamInvitationError('Invalid or expired invitation token');
194
228
  }
@@ -206,7 +240,7 @@ function createTeamInvitationService(deps, options) {
206
240
  }
207
241
  async function findByToken(accountId, token) {
208
242
  const all = await getInvitations(accountId);
209
- return all.find((i) => i.token === token && i.status === 'pending') ?? null;
243
+ return all.find((i) => i.status === 'pending' && invitationMatchesToken(i.token, token)) ?? null;
210
244
  }
211
245
  /**
212
246
  * Resolve emails for account members by looking up identities in the 'email' domain.
@@ -1 +1 @@
1
- {"version":3,"file":"team-invitation-service.js","sourceRoot":"","sources":["../src/team-invitation-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"team-invitation-service.js","sourceRoot":"","sources":["../src/team-invitation-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boopkit/cap-users",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "User accounts, authentication, and session management via Prisma",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -130,7 +130,7 @@ An API key is simultaneously an identity, a credential, and a bearer token. All
130
130
  | **Identity** | `domain: "api-key", key: "a3f1..."` — the SHA-256 of the key, as the cookie domain holds a session token. Lookup hashes the presented key and searches for that |
131
131
  | **Authentication** | `{ strategy: "api-key", accepted: true }` — user can use API keys |
132
132
  | **Credentials** | `{ strategy: "api-key", secret: "$2b$..." }` — bcrypt hash of the key |
133
- | **Authorization** | `{ identity_key: "47ZHJY-...", strategy: "api-key", trust: "authenticated", expires_at: 0 }` — standing per-key grant, still keyed on the **raw** key |
133
+ | **Authorization** | `{ identity_key: "a3f1...", strategy: "api-key", trust: "authenticated", expires_at: 0 }` — standing per-key grant, keyed on `hashToken(key)` (the same hash the identity row holds) |
134
134
 
135
135
  **Three independent levers to control access:**
136
136
  1. **Revoke the key** — end-date the identity. Immediate.
@@ -159,6 +159,10 @@ A request with no `Authorization` header passes through with `req.user` unset, s
159
159
  A token that does not resolve gets `401 { error: 'invalid_token' }` and a `WWW-Authenticate` challenge, and does **not** fall back to the session cookie — revoking a key has to stop the request even from a browser that is still logged in.
160
160
  It refuses a malformed token on every route it covers, open ones included, which is why the health check is mounted ahead of it: a route registered before `resolveBearer` never sees the middleware, so a monitor carrying a stale or garbled `Authorization` header still gets its `200` rather than a `401`.
161
161
 
162
+ `resolveBearer` is itself `createBearerMiddleware(deps, { resolve, strategy, challenge })` — exported from `@boopkit/cap-users` — with `validateApiKey` as the resolver and `'api-key'` as the strategy.
163
+ If your app issues another kind of bearer token, build a second middleware from that factory rather than writing one: you get the same parsing and the same refusal semantics, and both doors refuse instead of falling through to the cookie, which is what makes two of them safe on one header.
164
+ Give it its own strategy label — `req.authStrategy` is typed `string` so you can — because `requireApiKey` gates on the `'api-key'` literal, and reusing that label would let your token through the one gate that exists to demand a key.
165
+
162
166
  **Issuing a key is yours to design.**
163
167
  `authService.createApiKey(userId)` mints one and returns the raw key exactly once; the identity row holds its SHA-256 and the credentials entry a bcrypt hash, so nothing can hand it back later and any surface you build has to say so at the moment it is shown.
164
168
  This capability deliberately ships no route, screen, or command for it.
@@ -242,6 +246,32 @@ All services compose from `@boopkit/cap-services` primitives:
242
246
  | `userPropertyService` | `createUserPropertyService()` | Read/write user properties (credentials gated) |
243
247
  | `authService` | `createAuthService(deps, opts)` | Orchestrates signup, login, sessions, API keys |
244
248
 
249
+ ### IdentityService reads
250
+
251
+ Every read is bounded by a user id or an exact `(domain, key)` pair — except one.
252
+
253
+ `findAllByDomainAndKeyPrefix(domain, keyPrefix, opts?)` returns one page of the rows in a single
254
+ domain whose key starts with `keyPrefix`, for **any** user, in id order:
255
+
256
+ ```ts
257
+ const page = await identityService.findAllByDomainAndKeyPrefix('oauth-access', `${publicId}|`, {
258
+ includeEnded: true,
259
+ limit: 100, // clamped to 500
260
+ after: previousPage.nextCursor ?? undefined,
261
+ });
262
+ ```
263
+
264
+ It exists for credential domains whose keys are `"<issuer>|<secret hash>"` — cap-oauth-server's
265
+ token rows — where retiring one issuer means finding everybody it ever reached, and the operator
266
+ should not have to know the blast radius in advance. Left-anchored, the comparison is a seek on the
267
+ `(domain, key)` unique index rather than a table scan.
268
+
269
+ Both narrowings are load-bearing rather than ergonomic. The **domain is required**, so the scan
270
+ cannot wander into `email` or `api-key` rows; an **empty prefix throws**, because it would walk a
271
+ whole domain, which is the read this method exists to make unnecessary. It **pages** rather than
272
+ materialising a result set of unknown size: keep passing `nextCursor` back as `after` until it comes
273
+ back `null`.
274
+
245
275
  ### AuthService key operations
246
276
 
247
277
  **Signup**: `signup({ email, password, name })` — creates user, email identity, profile, credentials, auth method, session token, and authorization grant in one call. Each step is also available individually for graduated control.
@@ -258,9 +288,23 @@ The raw key is returned once and is not what `user_identities` holds: the row st
258
288
  To authenticate an HTTP request with one, mount `resolveBearer` — it reads `Authorization: Bearer <key>`, sets the same `req.user` the cookie path yields, and answers `401 { error: 'invalid_token' }` with a `WWW-Authenticate: Bearer` challenge when the token does not resolve.
259
289
  It never falls back to the session cookie, so revoking a key stops the request even from a browser that still holds a session.
260
290
 
261
- > The authorization *grant* still records the raw key as its `identity_key`, because that is the value callers pass to `isAuthorized` and `getTrustTier` and session grants store their token the same way.
262
- > `resolveBearer` depends on this: it records the presented raw key as `req.sessionToken` so the gate's `isAuthorized` call finds the per-key grant. Hashing the grant key and this middleware are two halves of one contract — change one and you must change the other.
263
- > Fixing that half consistently — grants and sessions together, with a migration that rehashes rather than logging everyone out — is tracked separately.
291
+ > The authorization *grant* records `hashToken(key)` as its `identity_key`, never the raw key — the same treatment the identity row and credential entry get. Session grants store their token the same way. `identity_key` is only ever compared for equality, so `setAuthorization` hashes the value it is handed, and `isAuthorized` / `getTrustTier` hash the raw token a caller presents before comparing. The raw value never lands in the readable `authorization` property.
292
+ > `resolveBearer` still records the presented **raw** key as `req.sessionToken`, and the gate calls `isAuthorized(user.id, req.sessionToken, …)`. That keeps working because `isAuthorized` hashes its argument — so the call site does **not** hash, and must not: hashing at both ends would double-hash and never match.
293
+
294
+ ### Migrating existing deployments
295
+
296
+ A deployment that stored grants before this fix keeps a raw session token or API key in each `authorization` row. The read path tolerates the old form permanently — it matches either `identity_key === hashToken(token)` or `identity_key === token` — so **nobody is logged out by upgrading**. The first time a raw grant is matched, the service logs one warning per process nudging you to migrate; it goes quiet on its own once the data is hashed.
297
+
298
+ `boop status` flags the un-migrated rows (its probe checks that every `authorization` row carries the `authorization-hashed-01` info_schema tag). To clear them, rehash in place:
299
+
300
+ ```bash
301
+ npm run credentials:migrate # REPORT ONLY — counts what would change, writes nothing
302
+ npm run credentials:migrate -- --run # apply the rehash
303
+ ```
304
+
305
+ The same tool and command also rehash **team invitation tokens**. An invitation token is a bearer credential — presenting it joins the account at the role the invitation grants — so it is hashed at rest exactly as session cookies and API keys are: the raw token is emailed to the invitee once and only its hash is stored in the `team_invitations` account-property, and `acceptInvitation` / `findByToken` hash the presented token before comparing. The read path tolerates a pre-fix row whose stored token is still raw (matching `token === hashToken(presented)` or `token === presented`), so **no pending invitation is voided by upgrading**, and it warns once per process until the data is migrated. `boop status` has a matching probe (every `team_invitations` row must carry the `team-invitations-hashed-01` tag), and the migration run above stamps it.
306
+
307
+ Because the raw values are still present, the tool rehashes them in place rather than invalidating them — every session, standing key, and pending invitation keeps working. It is **one-way and has no rollback**: once a row is rewritten the raw value is gone, so **take a database backup before `--run`**. Re-running is safe: a value that is already a SHA-256 digest is left untouched, so nothing is ever double-hashed.
264
308
 
265
309
  **Trust queries**: `getTrustTier(userId, identityKey)`, `isAuthorized(userId, identityKey, requiredTrust?)`.
266
310