@happyvertical/smrt-profiles 0.54.1 → 0.54.3

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.
Files changed (65) hide show
  1. package/AGENTS.md +1 -1
  2. package/dist/audit-trail.d.ts +24 -0
  3. package/dist/audit-trail.d.ts.map +1 -0
  4. package/dist/chunks/{ApiKey-BZmbOTnL.js → ApiKey-CVmlf3V6.js} +11 -3
  5. package/dist/chunks/ApiKey-CVmlf3V6.js.map +1 -0
  6. package/dist/chunks/{ApiKeyCollection-Bfb_nw81.js → ApiKeyCollection-CiiDNFdD.js} +3 -3
  7. package/dist/chunks/{ApiKeyCollection-Bfb_nw81.js.map → ApiKeyCollection-CiiDNFdD.js.map} +1 -1
  8. package/dist/chunks/{AuditLogCollection-B1YonCAP.js → AuditLogCollection-WDHL-_AF.js} +30 -12
  9. package/dist/chunks/AuditLogCollection-WDHL-_AF.js.map +1 -0
  10. package/dist/chunks/{NostrIdentity-n70E0vck.js → NostrIdentity-AC8fAdxe.js} +12 -4
  11. package/dist/chunks/{NostrIdentity-n70E0vck.js.map → NostrIdentity-AC8fAdxe.js.map} +1 -1
  12. package/dist/chunks/{NostrIdentityCollection-Ca74dkaL.js → NostrIdentityCollection-CctlECpX.js} +2 -2
  13. package/dist/chunks/{NostrIdentityCollection-Ca74dkaL.js.map → NostrIdentityCollection-CctlECpX.js.map} +1 -1
  14. package/dist/chunks/{OidcIdentity-Cb1bxreM.js → OidcIdentity-BjRu3n1g.js} +11 -3
  15. package/dist/chunks/OidcIdentity-BjRu3n1g.js.map +1 -0
  16. package/dist/chunks/{OidcIdentityCollection-TV8VdK69.js → OidcIdentityCollection-B4jYh36_.js} +3 -3
  17. package/dist/chunks/{OidcIdentityCollection-TV8VdK69.js.map → OidcIdentityCollection-B4jYh36_.js.map} +1 -1
  18. package/dist/chunks/{ProfileAssetCollection-B9hacUJa.js → ProfileAssetCollection-HeMtjBc0.js} +12 -3
  19. package/dist/chunks/ProfileAssetCollection-HeMtjBc0.js.map +1 -0
  20. package/dist/chunks/{ProfileCollection-DuJT7Mum.js → ProfileCollection-Bt6IJK49.js} +49 -25
  21. package/dist/chunks/ProfileCollection-Bt6IJK49.js.map +1 -0
  22. package/dist/chunks/{ProfileLinkCollection-4uNURz32.js → ProfileLinkCollection-u1hhzKTm.js} +11 -3
  23. package/dist/chunks/ProfileLinkCollection-u1hhzKTm.js.map +1 -0
  24. package/dist/chunks/{ProfileMetadataCollection-DQhbfEfa.js → ProfileMetadataCollection-BIYKy4Y3.js} +10 -2
  25. package/dist/chunks/ProfileMetadataCollection-BIYKy4Y3.js.map +1 -0
  26. package/dist/chunks/{ProfileMetafieldCollection-CoBuM_5G.js → ProfileMetafieldCollection-Buz7gzag.js} +10 -2
  27. package/dist/chunks/ProfileMetafieldCollection-Buz7gzag.js.map +1 -0
  28. package/dist/chunks/{ProfileRelationshipCollection-DUVgaIqf.js → ProfileRelationshipCollection-C4g_QLI4.js} +13 -5
  29. package/dist/chunks/ProfileRelationshipCollection-C4g_QLI4.js.map +1 -0
  30. package/dist/chunks/{ProfileRelationshipTermCollection-DtA9OM23.js → ProfileRelationshipTermCollection-C9J7mC7P.js} +10 -2
  31. package/dist/chunks/ProfileRelationshipTermCollection-C9J7mC7P.js.map +1 -0
  32. package/dist/chunks/{ProfileRelationshipType-BRiRka6t.js → ProfileRelationshipType-U7IwF6Wf.js} +10 -2
  33. package/dist/chunks/ProfileRelationshipType-U7IwF6Wf.js.map +1 -0
  34. package/dist/chunks/{ProfileRelationshipTypeCollection-BdXwd7Kf.js → ProfileRelationshipTypeCollection-_n22WqTb.js} +3 -3
  35. package/dist/chunks/{ProfileRelationshipTypeCollection-BdXwd7Kf.js.map → ProfileRelationshipTypeCollection-_n22WqTb.js.map} +1 -1
  36. package/dist/chunks/{oidcProvisioningPrimitives-D9OYu5-F.js → oidcProvisioningPrimitives-CYood-2M.js} +14 -4
  37. package/dist/chunks/{oidcProvisioningPrimitives-D9OYu5-F.js.map → oidcProvisioningPrimitives-CYood-2M.js.map} +1 -1
  38. package/dist/chunks/{resolveIdentity-B-PK6RwU.js → resolveIdentity-CvGDegU6.js} +16 -16
  39. package/dist/chunks/{resolveIdentity-B-PK6RwU.js.map → resolveIdentity-CvGDegU6.js.map} +1 -1
  40. package/dist/collections/AuditLogCollection.d.ts +3 -1
  41. package/dist/collections/AuditLogCollection.d.ts.map +1 -1
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +91 -24
  45. package/dist/index.js.map +1 -1
  46. package/dist/internal/oidc-provisioning.js +2 -2
  47. package/dist/manifest.json +126 -33
  48. package/dist/models/AuditLog.d.ts +9 -1
  49. package/dist/models/AuditLog.d.ts.map +1 -1
  50. package/dist/models/Profile.d.ts +2 -0
  51. package/dist/models/Profile.d.ts.map +1 -1
  52. package/dist/smrt-knowledge.json +62 -366
  53. package/dist/utils.js +4 -4
  54. package/package.json +12 -12
  55. package/dist/chunks/ApiKey-BZmbOTnL.js.map +0 -1
  56. package/dist/chunks/AuditLogCollection-B1YonCAP.js.map +0 -1
  57. package/dist/chunks/OidcIdentity-Cb1bxreM.js.map +0 -1
  58. package/dist/chunks/ProfileAssetCollection-B9hacUJa.js.map +0 -1
  59. package/dist/chunks/ProfileCollection-DuJT7Mum.js.map +0 -1
  60. package/dist/chunks/ProfileLinkCollection-4uNURz32.js.map +0 -1
  61. package/dist/chunks/ProfileMetadataCollection-DQhbfEfa.js.map +0 -1
  62. package/dist/chunks/ProfileMetafieldCollection-CoBuM_5G.js.map +0 -1
  63. package/dist/chunks/ProfileRelationshipCollection-DUVgaIqf.js.map +0 -1
  64. package/dist/chunks/ProfileRelationshipTermCollection-DtA9OM23.js.map +0 -1
  65. package/dist/chunks/ProfileRelationshipType-BRiRka6t.js.map +0 -1
@@ -1,15 +1,22 @@
1
- import { y as __exportAll } from "./NostrIdentity-n70E0vck.js";
1
+ import { y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
2
  import { SmrtObject, field, smrt } from "@happyvertical/smrt-core";
3
3
  //#region src/models/ProfileRelationshipType.ts
4
4
  var ProfileRelationshipType_exports = /* @__PURE__ */ __exportAll({ ProfileRelationshipType: () => ProfileRelationshipType });
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
8
+ enumerable: true,
9
+ configurable: true,
10
+ writable: true,
11
+ value
12
+ }) : obj[key] = value;
7
13
  var __decorateClass = (decorators, target, key, kind) => {
8
14
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
9
15
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
10
16
  if (kind && result) __defProp(target, key, result);
11
17
  return result;
12
18
  };
19
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
20
  function getReciprocalHandlers() {
14
21
  if (!globalThis.__smrtProfileRelationshipHandlers) globalThis.__smrtProfileRelationshipHandlers = /* @__PURE__ */ new Map();
15
22
  return globalThis.__smrtProfileRelationshipHandlers;
@@ -80,6 +87,7 @@ var ProfileRelationshipType = class extends SmrtObject {
80
87
  return (await ProfileRelationshipType.getBySlug(slug))?.reciprocal || false;
81
88
  }
82
89
  };
90
+ __publicField(ProfileRelationshipType, "__smrtPackage__", "@happyvertical/smrt-profiles");
83
91
  __decorateClass([field({ required: true })], ProfileRelationshipType.prototype, "name", 2);
84
92
  ProfileRelationshipType = __decorateClass([smrt({
85
93
  tableStrategy: "sti",
@@ -95,4 +103,4 @@ ProfileRelationshipType = __decorateClass([smrt({
95
103
  //#endregion
96
104
  export { ProfileRelationshipType_exports as n, ProfileRelationshipType as t };
97
105
 
98
- //# sourceMappingURL=ProfileRelationshipType-BRiRka6t.js.map
106
+ //# sourceMappingURL=ProfileRelationshipType-U7IwF6Wf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfileRelationshipType-U7IwF6Wf.js","names":[],"sources":["../../src/models/ProfileRelationshipType.ts"],"sourcesContent":["/**\n * ProfileRelationshipType model - Lookup table for relationship types\n *\n * Defines the kinds of relationships that can exist between profiles.\n * Uses UUID primary key with unique slug for human-readable lookups.\n */\n\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { ReciprocalHandler } from '../types';\n\nexport interface ProfileRelationshipTypeOptions extends SmrtObjectOptions {\n slug?: string;\n name?: string;\n reciprocal?: boolean;\n}\n\n/**\n * Extend globalThis to include reciprocal handlers registry.\n * Using globalThis ensures all module instances share the same handlers,\n * which is critical in monorepos where the same package can be loaded\n * from different paths (e.g., pnpm store vs workspace symlink).\n *\n * @see https://github.com/happyvertical/smrt/issues/543\n */\ndeclare global {\n // eslint-disable-next-line no-var\n var __smrtProfileRelationshipHandlers:\n | Map<string, ReciprocalHandler>\n | undefined;\n // eslint-disable-next-line no-var\n var __smrtProfileRelationshipHandlersInitialized: boolean | undefined;\n}\n\n/**\n * Get the reciprocal handlers Map from globalThis\n */\nfunction getReciprocalHandlers(): Map<string, ReciprocalHandler> {\n if (!globalThis.__smrtProfileRelationshipHandlers) {\n globalThis.__smrtProfileRelationshipHandlers = new Map<\n string,\n ReciprocalHandler\n >();\n }\n return globalThis.__smrtProfileRelationshipHandlers;\n}\n\n/**\n * Default handlers for common reciprocal relationship patterns\n */\nconst DEFAULT_HANDLERS: Record<string, ReciprocalHandler> = {\n // Symmetric relationships (same type in both directions)\n friend: async (from, to, context) => {\n await to.addRelationship(from, 'friend', context);\n },\n\n spouse: async (from, to) => {\n await to.addRelationship(from, 'spouse');\n },\n\n partner: async (from, to, context) => {\n await to.addRelationship(from, 'partner', context);\n },\n\n colleague: async (from, to, context) => {\n await to.addRelationship(from, 'colleague', context);\n },\n\n sibling: async (from, to) => {\n await to.addRelationship(from, 'sibling');\n },\n};\n\n// Register default handlers (only once across all module instances)\nif (!globalThis.__smrtProfileRelationshipHandlersInitialized) {\n globalThis.__smrtProfileRelationshipHandlersInitialized = true;\n for (const [slug, handler] of Object.entries(DEFAULT_HANDLERS)) {\n getReciprocalHandlers().set(slug, handler);\n }\n}\n\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class ProfileRelationshipType extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n // id: UUID (auto-generated by SmrtObject)\n // slug is inherited from SmrtObject (auto-generated from name)\n @field({ required: true })\n name: string = '';\n\n reciprocal: boolean = true; // True for two-way relationships\n\n constructor(options: ProfileRelationshipTypeOptions = {}) {\n super(options);\n if (options.name) this.name = options.name;\n if (options.reciprocal !== undefined) this.reciprocal = options.reciprocal;\n }\n\n /**\n * Convenience method for slug-based lookup\n *\n * @param slug - The slug to search for\n * @returns ProfileRelationshipType instance or null if not found\n */\n static async getBySlug(\n _slug: string,\n ): Promise<ProfileRelationshipType | null> {\n // Will be auto-implemented by SMRT\n return null;\n }\n\n /**\n * Register a custom reciprocal handler for a relationship type\n *\n * @param slug - The relationship type slug\n * @param handler - The handler function to execute when creating reciprocal relationship\n */\n static registerReciprocalHandler(\n slug: string,\n handler: ReciprocalHandler,\n ): void {\n getReciprocalHandlers().set(slug, handler);\n }\n\n /**\n * Get the reciprocal handler for a relationship type\n *\n * @param slug - The relationship type slug\n * @returns The handler function or undefined\n */\n static getReciprocalHandler(slug: string): ReciprocalHandler | undefined {\n return getReciprocalHandlers().get(slug);\n }\n\n /**\n * Check if a relationship type is reciprocal\n *\n * @param slug - The relationship type slug\n * @returns True if reciprocal, false otherwise\n */\n static async isReciprocal(slug: string): Promise<boolean> {\n const type = await ProfileRelationshipType.getBySlug(slug);\n return type?.reciprocal || false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAyCA,SAAS,wBAAwD;CAC/D,IAAI,CAAC,WAAW,mCACd,WAAW,oDAAoC,IAAI,IAGjD;CAEJ,OAAO,WAAW;AACpB;AAKA,IAAM,mBAAsD;CAE1D,QAAQ,OAAO,MAAM,IAAI,YAAY;EACnC,MAAM,GAAG,gBAAgB,MAAM,UAAU,OAAO;CAClD;CAEA,QAAQ,OAAO,MAAM,OAAO;EAC1B,MAAM,GAAG,gBAAgB,MAAM,QAAQ;CACzC;CAEA,SAAS,OAAO,MAAM,IAAI,YAAY;EACpC,MAAM,GAAG,gBAAgB,MAAM,WAAW,OAAO;CACnD;CAEA,WAAW,OAAO,MAAM,IAAI,YAAY;EACtC,MAAM,GAAG,gBAAgB,MAAM,aAAa,OAAO;CACrD;CAEA,SAAS,OAAO,MAAM,OAAO;EAC3B,MAAM,GAAG,gBAAgB,MAAM,SAAS;CAC1C;AACF;AAGA,IAAI,CAAC,WAAW,8CAA8C;CAC5D,WAAW,+CAA+C;CAC1D,KAAA,MAAW,CAAC,MAAM,YAAY,OAAO,QAAQ,gBAAgB,GAC3D,sBAAsB,CAAA,CAAE,IAAI,MAAM,OAAO;AAE7C;AAQO,IAAM,0BAAN,cAAsC,WAAW;CAItD,OAAe;CAEf,aAAsB;CAEtB,YAAY,UAA0C,CAAC,GAAG;EACxD,MAAM,OAAO;EACb,IAAI,QAAQ,MAAM,KAAK,OAAO,QAAQ;EACtC,IAAI,QAAQ,eAAe,KAAA,GAAW,KAAK,aAAa,QAAQ;CAClE;;;;;;;CAQA,aAAa,UACX,OACyC;EAEzC,OAAO;CACT;;;;;;;CAQA,OAAO,0BACL,MACA,SACM;EACN,sBAAsB,CAAA,CAAE,IAAI,MAAM,OAAO;CAC3C;;;;;;;CAQA,OAAO,qBAAqB,MAA6C;EACvE,OAAO,sBAAsB,CAAA,CAAE,IAAI,IAAI;CACzC;;;;;;;CAQA,aAAa,aAAa,MAAgC;EAExD,QAAO,MADY,wBAAwB,UAAU,IAAI,EAAA,EAC5C,cAAc;CAC7B;AACF;AA5D0D,cAA7C,yBAAoD,mBAAkB,8BAAA;AAIjF,gBAAA,CADC,MAAM,EAAE,UAAU,KAAK,CAAC,CAAA,GAHd,wBAIX,WAAA,QAAA,CAAA;AAJW,0BAAN,gBAAA,CANN,KAAK;CACJ,eAAe;CACf,KAAK,EAAE,SAAS;EAAC;EAAQ;EAAO;EAAU;CAAQ,EAAE;CACpD,KAAK,EAAE,SAAS,CAAC,QAAQ,KAAK,EAAE;CAChC,KAAK,EAAE,cAAc,KAAK;AAC5B,CAAC,CAAA,GACY,uBAAA"}
@@ -1,5 +1,5 @@
1
- import { y as __exportAll } from "./NostrIdentity-n70E0vck.js";
2
- import { t as ProfileRelationshipType } from "./ProfileRelationshipType-BRiRka6t.js";
1
+ import { y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
+ import { t as ProfileRelationshipType } from "./ProfileRelationshipType-U7IwF6Wf.js";
3
3
  import { SmrtCollection } from "@happyvertical/smrt-core";
4
4
  //#region src/collections/ProfileRelationshipTypeCollection.ts
5
5
  var ProfileRelationshipTypeCollection_exports = /* @__PURE__ */ __exportAll({ ProfileRelationshipTypeCollection: () => ProfileRelationshipTypeCollection });
@@ -51,4 +51,4 @@ var ProfileRelationshipTypeCollection = class extends SmrtCollection {
51
51
  //#endregion
52
52
  export { ProfileRelationshipTypeCollection_exports as n, ProfileRelationshipTypeCollection as t };
53
53
 
54
- //# sourceMappingURL=ProfileRelationshipTypeCollection-BdXwd7Kf.js.map
54
+ //# sourceMappingURL=ProfileRelationshipTypeCollection-_n22WqTb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileRelationshipTypeCollection-BdXwd7Kf.js","names":[],"sources":["../../src/collections/ProfileRelationshipTypeCollection.ts"],"sourcesContent":["/**\n * ProfileRelationshipTypeCollection - Collection manager for ProfileRelationshipType objects\n *\n * Provides querying for relationship type lookup table.\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { ProfileRelationshipType } from '../models/ProfileRelationshipType';\n\nexport class ProfileRelationshipTypeCollection extends SmrtCollection<ProfileRelationshipType> {\n static readonly _itemClass = ProfileRelationshipType;\n\n /**\n * Get relationship type by slug\n *\n * @param slug - The slug to search for\n * @returns ProfileRelationshipType instance or null\n */\n async getBySlug(slug: string): Promise<ProfileRelationshipType | null> {\n return await this.get({ slug });\n }\n\n /**\n * Get or create a relationship type by slug\n *\n * @param slug - The slug to search for\n * @param defaults - Default values if creating\n * @returns ProfileRelationshipType instance\n */\n async getOrCreateBySlug(\n slug: string,\n defaults: { name: string; reciprocal?: boolean },\n ): Promise<ProfileRelationshipType> {\n const existing = await this.getBySlug(slug);\n if (existing) return existing;\n\n const relationshipType = await this.create({ slug, ...defaults });\n await relationshipType.save();\n return relationshipType;\n }\n\n /**\n * Get all reciprocal relationship types\n *\n * @returns Array of reciprocal ProfileRelationshipType instances\n */\n async getReciprocal(): Promise<ProfileRelationshipType[]> {\n return await this.list({ where: { reciprocal: true } });\n }\n\n /**\n * Get all directional (non-reciprocal) relationship types\n *\n * @returns Array of directional ProfileRelationshipType instances\n */\n async getDirectional(): Promise<ProfileRelationshipType[]> {\n return await this.list({ where: { reciprocal: false } });\n }\n}\n"],"mappings":";;;;;AASO,IAAM,oCAAN,cAAgD,eAAwC;CAC7F,OAAgB,aAAa;;;;;;;CAQ7B,MAAM,UAAU,MAAuD;EACrE,OAAO,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC;CAChC;;;;;;;;CASA,MAAM,kBACJ,MACA,UACkC;EAClC,MAAM,WAAW,MAAM,KAAK,UAAU,IAAI;EAC1C,IAAI,UAAU,OAAO;EAErB,MAAM,mBAAmB,MAAM,KAAK,OAAO;GAAE;GAAM,GAAG;EAAS,CAAC;EAChE,MAAM,iBAAiB,KAAK;EAC5B,OAAO;CACT;;;;;;CAOA,MAAM,gBAAoD;EACxD,OAAO,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,YAAY,KAAK,EAAE,CAAC;CACxD;;;;;;CAOA,MAAM,iBAAqD;EACzD,OAAO,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,YAAY,MAAM,EAAE,CAAC;CACzD;AACF"}
1
+ {"version":3,"file":"ProfileRelationshipTypeCollection-_n22WqTb.js","names":[],"sources":["../../src/collections/ProfileRelationshipTypeCollection.ts"],"sourcesContent":["/**\n * ProfileRelationshipTypeCollection - Collection manager for ProfileRelationshipType objects\n *\n * Provides querying for relationship type lookup table.\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { ProfileRelationshipType } from '../models/ProfileRelationshipType';\n\nexport class ProfileRelationshipTypeCollection extends SmrtCollection<ProfileRelationshipType> {\n static readonly _itemClass = ProfileRelationshipType;\n\n /**\n * Get relationship type by slug\n *\n * @param slug - The slug to search for\n * @returns ProfileRelationshipType instance or null\n */\n async getBySlug(slug: string): Promise<ProfileRelationshipType | null> {\n return await this.get({ slug });\n }\n\n /**\n * Get or create a relationship type by slug\n *\n * @param slug - The slug to search for\n * @param defaults - Default values if creating\n * @returns ProfileRelationshipType instance\n */\n async getOrCreateBySlug(\n slug: string,\n defaults: { name: string; reciprocal?: boolean },\n ): Promise<ProfileRelationshipType> {\n const existing = await this.getBySlug(slug);\n if (existing) return existing;\n\n const relationshipType = await this.create({ slug, ...defaults });\n await relationshipType.save();\n return relationshipType;\n }\n\n /**\n * Get all reciprocal relationship types\n *\n * @returns Array of reciprocal ProfileRelationshipType instances\n */\n async getReciprocal(): Promise<ProfileRelationshipType[]> {\n return await this.list({ where: { reciprocal: true } });\n }\n\n /**\n * Get all directional (non-reciprocal) relationship types\n *\n * @returns Array of directional ProfileRelationshipType instances\n */\n async getDirectional(): Promise<ProfileRelationshipType[]> {\n return await this.list({ where: { reciprocal: false } });\n }\n}\n"],"mappings":";;;;;AASO,IAAM,oCAAN,cAAgD,eAAwC;CAC7F,OAAgB,aAAa;;;;;;;CAQ7B,MAAM,UAAU,MAAuD;EACrE,OAAO,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC;CAChC;;;;;;;;CASA,MAAM,kBACJ,MACA,UACkC;EAClC,MAAM,WAAW,MAAM,KAAK,UAAU,IAAI;EAC1C,IAAI,UAAU,OAAO;EAErB,MAAM,mBAAmB,MAAM,KAAK,OAAO;GAAE;GAAM,GAAG;EAAS,CAAC;EAChE,MAAM,iBAAiB,KAAK;EAC5B,OAAO;CACT;;;;;;CAOA,MAAM,gBAAoD;EACxD,OAAO,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,YAAY,KAAK,EAAE,CAAC;CACxD;;;;;;CAOA,MAAM,iBAAqD;EACzD,OAAO,MAAM,KAAK,KAAK,EAAE,OAAO,EAAE,YAAY,MAAM,EAAE,CAAC;CACzD;AACF"}
@@ -1,6 +1,6 @@
1
- import { y as __exportAll } from "./NostrIdentity-n70E0vck.js";
2
- import { a as Profile, f as saveOidcRaceArbiter, m as ProfileType, n as ProfileCollection } from "./ProfileCollection-DuJT7Mum.js";
3
- import { t as OidcIdentity } from "./OidcIdentity-Cb1bxreM.js";
1
+ import { y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
+ import { a as Profile, f as saveOidcRaceArbiter, m as ProfileType, n as ProfileCollection } from "./ProfileCollection-Bt6IJK49.js";
3
+ import { t as OidcIdentity } from "./OidcIdentity-BjRu3n1g.js";
4
4
  import { SmrtCollection, smrt } from "@happyvertical/smrt-core";
5
5
  import { isSystemContext } from "@happyvertical/smrt-tenancy";
6
6
  //#region src/collections/ProfileTypeCollection.ts
@@ -89,29 +89,39 @@ var ProfileTypes_exports = /* @__PURE__ */ __exportAll({
89
89
  });
90
90
  var __defProp = Object.defineProperty;
91
91
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
92
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value
97
+ }) : obj[key] = value;
92
98
  var __decorateClass = (decorators, target, key, kind) => {
93
99
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
94
100
  for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
95
101
  if (kind && result) __defProp(target, key, result);
96
102
  return result;
97
103
  };
104
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
98
105
  var Person = class extends Profile {
99
106
  constructor(options = {}) {
100
107
  super(options);
101
108
  }
102
109
  };
110
+ __publicField(Person, "__smrtPackage__", "@happyvertical/smrt-profiles");
103
111
  Person = __decorateClass([smrt({ tableStrategy: "sti" })], Person);
104
112
  var Organization = class extends Profile {
105
113
  constructor(options = {}) {
106
114
  super(options);
107
115
  }
108
116
  };
117
+ __publicField(Organization, "__smrtPackage__", "@happyvertical/smrt-profiles");
109
118
  Organization = __decorateClass([smrt({ tableStrategy: "sti" })], Organization);
110
119
  var Bot = class extends Profile {
111
120
  constructor(options = {}) {
112
121
  super(options);
113
122
  }
114
123
  };
124
+ __publicField(Bot, "__smrtPackage__", "@happyvertical/smrt-profiles");
115
125
  Bot = __decorateClass([smrt({ tableStrategy: "sti" })], Bot);
116
126
  //#endregion
117
127
  //#region src/auth/oidcProvisioningPrimitives.ts
@@ -153,4 +163,4 @@ function requireProvisioningId(value, label) {
153
163
  //#endregion
154
164
  export { Person as a, ProfileTypeCollection_exports as c, Organization as i, insertOidcProvisioningIdentity as n, ProfileTypes_exports as o, Bot as r, ProfileTypeCollection as s, createOidcProvisioningPerson as t };
155
165
 
156
- //# sourceMappingURL=oidcProvisioningPrimitives-D9OYu5-F.js.map
166
+ //# sourceMappingURL=oidcProvisioningPrimitives-CYood-2M.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oidcProvisioningPrimitives-D9OYu5-F.js","names":[],"sources":["../../src/collections/ProfileTypeCollection.ts","../../src/models/ProfileTypes.ts","../../src/auth/oidcProvisioningPrimitives.ts"],"sourcesContent":["/**\n * ProfileTypeCollection - Collection manager for ProfileType objects\n *\n * Provides querying for profile type lookup table.\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { isSystemContext } from '@happyvertical/smrt-tenancy';\nimport { ProfileType } from '../models/ProfileType';\n\nfunction isPostgresUrl(url: string | undefined): boolean {\n return /^postgres(?:ql)?:/iu.test(url ?? '');\n}\n\nexport class ProfileTypeCollection extends SmrtCollection<ProfileType> {\n static readonly _itemClass = ProfileType;\n\n /**\n * Get profile type by slug\n *\n * @param slug - The slug to search for\n * @returns ProfileType instance or null\n */\n async getBySlug(slug: string): Promise<ProfileType | null> {\n return await this.get({ slug });\n }\n\n /**\n * Get or create a profile type by slug\n *\n * @param slug - The slug to search for\n * @param defaults - Default values if creating\n * @returns ProfileType instance\n */\n async getOrCreateBySlug(\n slug: string,\n defaults: { name: string; description?: string },\n ): Promise<ProfileType> {\n const existing = await this.getBySlug(slug);\n if (existing) return existing;\n\n const profileType = await this.create({ slug, ...defaults });\n await profileType.save();\n return profileType;\n }\n\n /**\n * Atomically create or load a global ProfileType from trusted system code.\n *\n * This intentionally bypasses tenant auto-population and therefore refuses\n * to run outside an explicit `withSystemContext()` boundary.\n */\n async getOrCreateGlobalBySlug(\n slug: string,\n defaults: { name: string; description?: string },\n ): Promise<ProfileType> {\n if (!isSystemContext()) {\n throw new Error(\n 'Global ProfileType creation requires an explicit system context.',\n );\n }\n\n const existing = await this.loadGlobalBySlug(slug);\n if (existing) return existing;\n\n // A plain SMRT create is an upsert and may replace the winning row's id\n // when two first-login transactions race. Keep the canonical id stable by\n // using a cross-adapter insert-if-absent and then hydrating the winner.\n //\n // The table's unique key is `(tenant_id, slug, context, _meta_type)` since\n // smrt#2360, and a global row's NULL tenant never conflicts at the\n // database level (NULLs are distinct in a unique index), so a raw\n // `ON CONFLICT (…) DO NOTHING` can no longer arbitrate this race. Serialize\n // the global create per slug instead: PostgreSQL through a\n // transaction-scoped advisory lock (the arbiter the SDK's null-aware\n // upsert uses too); the embedded engines through the provisioning\n // coordinator's in-process lock plus their single-writer transactions.\n const insertIfAbsent = async (db: typeof this.db): Promise<void> => {\n if (isPostgresUrl(db.url)) {\n await db.query(\n 'SELECT pg_advisory_xact_lock(hashtext(?), hashtext(?))',\n '@happyvertical/smrt-profiles:profile_types:global',\n slug,\n );\n }\n await db.query(\n `INSERT INTO profile_types\n (id, slug, context, _meta_type, tenant_id, name, description)\n SELECT ?, ?, '', '@happyvertical/smrt-profiles:ProfileType', NULL, ?, ?\n WHERE NOT EXISTS (\n SELECT 1 FROM profile_types\n WHERE slug = ?\n AND context = ''\n AND _meta_type = '@happyvertical/smrt-profiles:ProfileType'\n AND tenant_id IS NULL\n )`,\n crypto.randomUUID(),\n slug,\n defaults.name,\n defaults.description ?? null,\n slug,\n );\n };\n\n // A transaction-scoped advisory lock only spans both statements when they\n // run on one transaction. On PostgreSQL, any handle that is NOT already\n // transaction-bound may route each query to a different pooled connection\n // — a root adapter (`beginTransaction` present) and equally a view\n // wrapper (only `transaction()` present) — so open a transaction for the\n // pair on every such handle. A transaction-bound handle (fingerprint: it\n // carries `commit`) already keeps both statements on one client and must\n // not nest. Embedded engines run directly: a nested root transaction\n // would deadlock their single-writer adapters, and the provisioning\n // coordinator's in-process lock already serializes them.\n const isTransactionBound =\n typeof (this.db as { commit?: unknown }).commit === 'function';\n if (\n isPostgresUrl(this.db.url) &&\n !isTransactionBound &&\n typeof this.db.transaction === 'function'\n ) {\n await this.db.transaction((tx) => insertIfAbsent(tx));\n } else {\n await insertIfAbsent(this.db);\n }\n const profileType = await this.loadGlobalBySlug(slug);\n if (!profileType) {\n throw new Error(\n `Global ProfileType '${slug}' could not be created or loaded.`,\n );\n }\n return profileType;\n }\n\n private async loadGlobalBySlug(slug: string): Promise<ProfileType | null> {\n const result = await this.db.query(\n `SELECT CAST(id AS VARCHAR) AS id\n FROM profile_types\n WHERE slug = ?\n AND context = ''\n AND _meta_type = '@happyvertical/smrt-profiles:ProfileType'\n AND tenant_id IS NULL\n LIMIT 1`,\n slug,\n );\n const id = result.rows[0]?.id;\n if (typeof id !== 'string') return null;\n const profileType = await this.get({ id });\n // @happyvertical/sql 0.88 exposes native DuckDB UUID result values as an\n // internal object. The cast above is the portable identity boundary for\n // this lookup; retain it on the hydrated object used by provisioning.\n if (profileType) profileType.id = id;\n return profileType;\n }\n}\n","/**\n * Profile subclasses for STI (Single Table Inheritance)\n *\n * These classes inherit from Profile and automatically use the shared\n * profiles table with _meta_type discriminator.\n */\n\nimport { smrt } from '@happyvertical/smrt-core';\nimport { Profile, type ProfileOptions } from './Profile';\n\n/**\n * Person profile type\n *\n * Represents individual people/users.\n */\n@smrt({\n tableStrategy: 'sti',\n})\nexport class Person extends Profile {\n constructor(options: ProfileOptions = {}) {\n super(options);\n // Person-specific initialization can go here\n }\n}\n\n/**\n * Organization profile type\n *\n * Represents companies, groups, institutions, and other organizational entities.\n */\n@smrt({\n tableStrategy: 'sti',\n})\nexport class Organization extends Profile {\n constructor(options: ProfileOptions = {}) {\n super(options);\n // Organization-specific initialization can go here\n }\n}\n\n/**\n * Bot profile type\n *\n * Represents automated agents, bots, and AI entities.\n */\n@smrt({\n tableStrategy: 'sti',\n})\nexport class Bot extends Profile {\n constructor(options: ProfileOptions = {}) {\n super(options);\n // Bot-specific initialization can go here\n }\n}\n","import type { getDatabase } from '@happyvertical/sql';\nimport { ProfileCollection } from '../collections/ProfileCollection';\nimport { ProfileTypeCollection } from '../collections/ProfileTypeCollection';\nimport { OidcIdentity } from '../models/OidcIdentity';\nimport type { Profile } from '../models/Profile';\nimport { Person } from '../models/ProfileTypes';\nimport { saveOidcRaceArbiter } from './oidcProvisioningCoordinator';\n\ntype DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;\n\nexport interface OidcProvisioningPersonInput {\n email?: string;\n name?: string;\n preferredUsername?: string;\n subject: string;\n}\n\nexport interface OidcProvisioningIdentityInput {\n email?: string;\n issuer: string;\n profileId: string;\n provider: string;\n subject: string;\n}\n\n/** Create and reserve a fresh global Person inside the caller's transaction. */\nexport async function createOidcProvisioningPerson(\n db: DatabaseInterface,\n input: OidcProvisioningPersonInput,\n): Promise<Profile> {\n const typeCollection = await ProfileTypeCollection.create({ db });\n const personType = await typeCollection.getOrCreateGlobalBySlug('person', {\n name: 'Person',\n description: 'Individual person profile',\n });\n const typeId = requireProvisioningId(personType.id, 'Person ProfileType');\n let profile: Profile = new Person({\n db,\n // OIDC display names are not identity keys. A per-profile slug keeps\n // SMRT's natural-key upsert from replacing an unrelated Person.\n slug: `oidc-${crypto.randomUUID()}`,\n tenantId: null,\n typeId,\n email: input.email ?? '',\n name: input.name || input.preferredUsername || input.subject,\n });\n await profile.initialize();\n await saveOidcRaceArbiter(() => profile.save());\n\n if (input.email) {\n const profiles = await ProfileCollection.create({ db });\n profile = await profiles.reserveCanonicalIdentityEmail(\n requireProvisioningId(profile.id, 'Created Profile'),\n input.email,\n );\n }\n return profile;\n}\n\n/** Insert the identity after the caller proves Profile ownership. */\nexport async function insertOidcProvisioningIdentity(\n db: DatabaseInterface,\n input: OidcProvisioningIdentityInput,\n): Promise<OidcIdentity> {\n const identity = new OidcIdentity({\n db,\n email: input.email ?? '',\n issuer: input.issuer,\n profileId: input.profileId,\n provider: input.provider,\n subject: input.subject,\n });\n await identity.initialize();\n await saveOidcRaceArbiter(() => identity.save());\n return identity;\n}\n\nfunction requireProvisioningId(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value) {\n throw new Error(`${label} did not produce an id.`);\n }\n return value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"oidcProvisioningPrimitives-CYood-2M.js","names":[],"sources":["../../src/collections/ProfileTypeCollection.ts","../../src/models/ProfileTypes.ts","../../src/auth/oidcProvisioningPrimitives.ts"],"sourcesContent":["/**\n * ProfileTypeCollection - Collection manager for ProfileType objects\n *\n * Provides querying for profile type lookup table.\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { isSystemContext } from '@happyvertical/smrt-tenancy';\nimport { ProfileType } from '../models/ProfileType';\n\nfunction isPostgresUrl(url: string | undefined): boolean {\n return /^postgres(?:ql)?:/iu.test(url ?? '');\n}\n\nexport class ProfileTypeCollection extends SmrtCollection<ProfileType> {\n static readonly _itemClass = ProfileType;\n\n /**\n * Get profile type by slug\n *\n * @param slug - The slug to search for\n * @returns ProfileType instance or null\n */\n async getBySlug(slug: string): Promise<ProfileType | null> {\n return await this.get({ slug });\n }\n\n /**\n * Get or create a profile type by slug\n *\n * @param slug - The slug to search for\n * @param defaults - Default values if creating\n * @returns ProfileType instance\n */\n async getOrCreateBySlug(\n slug: string,\n defaults: { name: string; description?: string },\n ): Promise<ProfileType> {\n const existing = await this.getBySlug(slug);\n if (existing) return existing;\n\n const profileType = await this.create({ slug, ...defaults });\n await profileType.save();\n return profileType;\n }\n\n /**\n * Atomically create or load a global ProfileType from trusted system code.\n *\n * This intentionally bypasses tenant auto-population and therefore refuses\n * to run outside an explicit `withSystemContext()` boundary.\n */\n async getOrCreateGlobalBySlug(\n slug: string,\n defaults: { name: string; description?: string },\n ): Promise<ProfileType> {\n if (!isSystemContext()) {\n throw new Error(\n 'Global ProfileType creation requires an explicit system context.',\n );\n }\n\n const existing = await this.loadGlobalBySlug(slug);\n if (existing) return existing;\n\n // A plain SMRT create is an upsert and may replace the winning row's id\n // when two first-login transactions race. Keep the canonical id stable by\n // using a cross-adapter insert-if-absent and then hydrating the winner.\n //\n // The table's unique key is `(tenant_id, slug, context, _meta_type)` since\n // smrt#2360, and a global row's NULL tenant never conflicts at the\n // database level (NULLs are distinct in a unique index), so a raw\n // `ON CONFLICT (…) DO NOTHING` can no longer arbitrate this race. Serialize\n // the global create per slug instead: PostgreSQL through a\n // transaction-scoped advisory lock (the arbiter the SDK's null-aware\n // upsert uses too); the embedded engines through the provisioning\n // coordinator's in-process lock plus their single-writer transactions.\n const insertIfAbsent = async (db: typeof this.db): Promise<void> => {\n if (isPostgresUrl(db.url)) {\n await db.query(\n 'SELECT pg_advisory_xact_lock(hashtext(?), hashtext(?))',\n '@happyvertical/smrt-profiles:profile_types:global',\n slug,\n );\n }\n await db.query(\n `INSERT INTO profile_types\n (id, slug, context, _meta_type, tenant_id, name, description)\n SELECT ?, ?, '', '@happyvertical/smrt-profiles:ProfileType', NULL, ?, ?\n WHERE NOT EXISTS (\n SELECT 1 FROM profile_types\n WHERE slug = ?\n AND context = ''\n AND _meta_type = '@happyvertical/smrt-profiles:ProfileType'\n AND tenant_id IS NULL\n )`,\n crypto.randomUUID(),\n slug,\n defaults.name,\n defaults.description ?? null,\n slug,\n );\n };\n\n // A transaction-scoped advisory lock only spans both statements when they\n // run on one transaction. On PostgreSQL, any handle that is NOT already\n // transaction-bound may route each query to a different pooled connection\n // — a root adapter (`beginTransaction` present) and equally a view\n // wrapper (only `transaction()` present) — so open a transaction for the\n // pair on every such handle. A transaction-bound handle (fingerprint: it\n // carries `commit`) already keeps both statements on one client and must\n // not nest. Embedded engines run directly: a nested root transaction\n // would deadlock their single-writer adapters, and the provisioning\n // coordinator's in-process lock already serializes them.\n const isTransactionBound =\n typeof (this.db as { commit?: unknown }).commit === 'function';\n if (\n isPostgresUrl(this.db.url) &&\n !isTransactionBound &&\n typeof this.db.transaction === 'function'\n ) {\n await this.db.transaction((tx) => insertIfAbsent(tx));\n } else {\n await insertIfAbsent(this.db);\n }\n const profileType = await this.loadGlobalBySlug(slug);\n if (!profileType) {\n throw new Error(\n `Global ProfileType '${slug}' could not be created or loaded.`,\n );\n }\n return profileType;\n }\n\n private async loadGlobalBySlug(slug: string): Promise<ProfileType | null> {\n const result = await this.db.query(\n `SELECT CAST(id AS VARCHAR) AS id\n FROM profile_types\n WHERE slug = ?\n AND context = ''\n AND _meta_type = '@happyvertical/smrt-profiles:ProfileType'\n AND tenant_id IS NULL\n LIMIT 1`,\n slug,\n );\n const id = result.rows[0]?.id;\n if (typeof id !== 'string') return null;\n const profileType = await this.get({ id });\n // @happyvertical/sql 0.88 exposes native DuckDB UUID result values as an\n // internal object. The cast above is the portable identity boundary for\n // this lookup; retain it on the hydrated object used by provisioning.\n if (profileType) profileType.id = id;\n return profileType;\n }\n}\n","/**\n * Profile subclasses for STI (Single Table Inheritance)\n *\n * These classes inherit from Profile and automatically use the shared\n * profiles table with _meta_type discriminator.\n */\n\nimport { smrt } from '@happyvertical/smrt-core';\nimport { Profile, type ProfileOptions } from './Profile';\n\n/**\n * Person profile type\n *\n * Represents individual people/users.\n */\n@smrt({\n tableStrategy: 'sti',\n})\nexport class Person extends Profile { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n constructor(options: ProfileOptions = {}) {\n super(options);\n // Person-specific initialization can go here\n }\n}\n\n/**\n * Organization profile type\n *\n * Represents companies, groups, institutions, and other organizational entities.\n */\n@smrt({\n tableStrategy: 'sti',\n})\nexport class Organization extends Profile { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n constructor(options: ProfileOptions = {}) {\n super(options);\n // Organization-specific initialization can go here\n }\n}\n\n/**\n * Bot profile type\n *\n * Represents automated agents, bots, and AI entities.\n */\n@smrt({\n tableStrategy: 'sti',\n})\nexport class Bot extends Profile { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n constructor(options: ProfileOptions = {}) {\n super(options);\n // Bot-specific initialization can go here\n }\n}\n","import type { getDatabase } from '@happyvertical/sql';\nimport { ProfileCollection } from '../collections/ProfileCollection';\nimport { ProfileTypeCollection } from '../collections/ProfileTypeCollection';\nimport { OidcIdentity } from '../models/OidcIdentity';\nimport type { Profile } from '../models/Profile';\nimport { Person } from '../models/ProfileTypes';\nimport { saveOidcRaceArbiter } from './oidcProvisioningCoordinator';\n\ntype DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;\n\nexport interface OidcProvisioningPersonInput {\n email?: string;\n name?: string;\n preferredUsername?: string;\n subject: string;\n}\n\nexport interface OidcProvisioningIdentityInput {\n email?: string;\n issuer: string;\n profileId: string;\n provider: string;\n subject: string;\n}\n\n/** Create and reserve a fresh global Person inside the caller's transaction. */\nexport async function createOidcProvisioningPerson(\n db: DatabaseInterface,\n input: OidcProvisioningPersonInput,\n): Promise<Profile> {\n const typeCollection = await ProfileTypeCollection.create({ db });\n const personType = await typeCollection.getOrCreateGlobalBySlug('person', {\n name: 'Person',\n description: 'Individual person profile',\n });\n const typeId = requireProvisioningId(personType.id, 'Person ProfileType');\n let profile: Profile = new Person({\n db,\n // OIDC display names are not identity keys. A per-profile slug keeps\n // SMRT's natural-key upsert from replacing an unrelated Person.\n slug: `oidc-${crypto.randomUUID()}`,\n tenantId: null,\n typeId,\n email: input.email ?? '',\n name: input.name || input.preferredUsername || input.subject,\n });\n await profile.initialize();\n await saveOidcRaceArbiter(() => profile.save());\n\n if (input.email) {\n const profiles = await ProfileCollection.create({ db });\n profile = await profiles.reserveCanonicalIdentityEmail(\n requireProvisioningId(profile.id, 'Created Profile'),\n input.email,\n );\n }\n return profile;\n}\n\n/** Insert the identity after the caller proves Profile ownership. */\nexport async function insertOidcProvisioningIdentity(\n db: DatabaseInterface,\n input: OidcProvisioningIdentityInput,\n): Promise<OidcIdentity> {\n const identity = new OidcIdentity({\n db,\n email: input.email ?? '',\n issuer: input.issuer,\n profileId: input.profileId,\n provider: input.provider,\n subject: input.subject,\n });\n await identity.initialize();\n await saveOidcRaceArbiter(() => identity.save());\n return identity;\n}\n\nfunction requireProvisioningId(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value) {\n throw new Error(`${label} did not produce an id.`);\n }\n return value;\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { _ as verifyAuthEvent, t as NostrIdentity, y as __exportAll } from "./NostrIdentity-n70E0vck.js";
2
- import { d as isOidcProvisioningRaceConflict, l as coordinateOidcProvisioning, p as normalizeIdentityEmail } from "./ProfileCollection-DuJT7Mum.js";
3
- import { n as insertOidcProvisioningIdentity, t as createOidcProvisioningPerson } from "./oidcProvisioningPrimitives-D9OYu5-F.js";
4
- import { t as ApiKey } from "./ApiKey-BZmbOTnL.js";
5
- import { t as OidcIdentity } from "./OidcIdentity-Cb1bxreM.js";
1
+ import { _ as verifyAuthEvent, t as NostrIdentity, y as __exportAll } from "./NostrIdentity-AC8fAdxe.js";
2
+ import { d as isOidcProvisioningRaceConflict, l as coordinateOidcProvisioning, p as normalizeIdentityEmail } from "./ProfileCollection-Bt6IJK49.js";
3
+ import { n as insertOidcProvisioningIdentity, t as createOidcProvisioningPerson } from "./oidcProvisioningPrimitives-CYood-2M.js";
4
+ import { t as ApiKey } from "./ApiKey-CVmlf3V6.js";
5
+ import { t as OidcIdentity } from "./OidcIdentity-BjRu3n1g.js";
6
6
  import { resolveDatabase } from "@happyvertical/smrt-core";
7
7
  import { withSystemContext } from "@happyvertical/smrt-tenancy";
8
8
  //#region src/auth/resolveIdentity.ts
@@ -65,13 +65,13 @@ async function resolveIdentity(context) {
65
65
  };
66
66
  }
67
67
  async function findProfileByExternalId(provider, externalId, options) {
68
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
68
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
69
69
  const identities = await (await OidcIdentityCollection.create(options)).findByProvider(provider);
70
70
  for (const identity of identities) if (identity.subject === externalId || identity.email?.includes(externalId)) {
71
71
  const profile = await identity.getProfile();
72
72
  if (profile) return profile;
73
73
  }
74
- const { ProfileCollection } = await import("./ProfileCollection-DuJT7Mum.js").then((n) => n.r);
74
+ const { ProfileCollection } = await import("./ProfileCollection-Bt6IJK49.js").then((n) => n.r);
75
75
  const profiles = await (await ProfileCollection.create(options)).list({
76
76
  where: { email: `${externalId}@users.noreply.github.com` },
77
77
  limit: 1
@@ -92,7 +92,7 @@ async function reuseExistingOidcIdentityForProfile(profileId, claims, provider,
92
92
  createConcurrencyError: (cause) => new Error("Concurrent exact OIDC identity reuse did not converge.", cause === void 0 ? void 0 : { cause }),
93
93
  rebindRootResult: rebindOidcProfileResult,
94
94
  provision: (tx) => withSystemContext(async () => {
95
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
95
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
96
96
  const identity = await (await OidcIdentityCollection.create({ db: tx })).findBySubject(normalizedClaims.iss, normalizedClaims.sub);
97
97
  if (!identity) throw new Error("OidcIdentity.findOrCreate() no longer creates authentication links; use UserCollection.getOrCreateFromOidc() or createProfileFromOidc().");
98
98
  if (identity.profileId !== profileId) throw new Error(`OIDC identity ${normalizedClaims.iss} subject ${normalizedClaims.sub} belongs to a different Profile.`);
@@ -126,7 +126,7 @@ async function coordinateProfileOidcProvisioning(claims, provider, options) {
126
126
  });
127
127
  }
128
128
  async function provisionOidcProfile(claims, provider, options) {
129
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
129
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
130
130
  const existingIdentity = await (await OidcIdentityCollection.create(options)).findBySubject(claims.iss, claims.sub);
131
131
  if (existingIdentity) {
132
132
  const profile2 = await existingIdentity.getProfile();
@@ -141,7 +141,7 @@ async function provisionOidcProfile(claims, provider, options) {
141
141
  created: false
142
142
  };
143
143
  }
144
- const { ProfileCollection } = await import("./ProfileCollection-DuJT7Mum.js").then((n) => n.r);
144
+ const { ProfileCollection } = await import("./ProfileCollection-Bt6IJK49.js").then((n) => n.r);
145
145
  const profileCollection = await ProfileCollection.create(options);
146
146
  if (claims.email) {
147
147
  if (await profileCollection.findUniqueGlobalPersonByEmail(claims.email)) {
@@ -168,8 +168,8 @@ async function provisionOidcProfile(claims, provider, options) {
168
168
  };
169
169
  }
170
170
  async function rebindOidcProfileResult(result, rootDb) {
171
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-TV8VdK69.js").then((n) => n.r);
172
- const { ProfileCollection } = await import("./ProfileCollection-DuJT7Mum.js").then((n) => n.r);
171
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-B4jYh36_.js").then((n) => n.r);
172
+ const { ProfileCollection } = await import("./ProfileCollection-Bt6IJK49.js").then((n) => n.r);
173
173
  const profileId = requireOidcProfileId(result.profile.id);
174
174
  const identityId = requireOidcProfileId(result.oidcIdentity.id);
175
175
  const [profile, oidcIdentity] = await withSystemContext(async () => {
@@ -218,11 +218,11 @@ async function createProfileFromNostr(email, nostrData, options) {
218
218
  created: false
219
219
  };
220
220
  }
221
- const { Person } = await import("./oidcProvisioningPrimitives-D9OYu5-F.js").then((n) => n.o);
222
- const { ProfileTypeCollection } = await import("./oidcProvisioningPrimitives-D9OYu5-F.js").then((n) => n.c);
221
+ const { Person } = await import("./oidcProvisioningPrimitives-CYood-2M.js").then((n) => n.o);
222
+ const { ProfileTypeCollection } = await import("./oidcProvisioningPrimitives-CYood-2M.js").then((n) => n.c);
223
223
  let personType = await (await ProfileTypeCollection.create(options)).getBySlug("person");
224
224
  if (!personType) {
225
- const { ProfileType } = await import("./ProfileCollection-DuJT7Mum.js").then((n) => n.h);
225
+ const { ProfileType } = await import("./ProfileCollection-Bt6IJK49.js").then((n) => n.h);
226
226
  personType = new ProfileType({
227
227
  ...options,
228
228
  slug: "person",
@@ -261,4 +261,4 @@ async function createProfileFromNostr(email, nostrData, options) {
261
261
  //#endregion
262
262
  export { resolveIdentity_exports as i, createProfileFromOidc as n, resolveIdentity as r, createProfileFromNostr as t };
263
263
 
264
- //# sourceMappingURL=resolveIdentity-B-PK6RwU.js.map
264
+ //# sourceMappingURL=resolveIdentity-CvGDegU6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveIdentity-B-PK6RwU.js","names":["profile"],"sources":["../../src/auth/resolveIdentity.ts"],"sourcesContent":["/**\n * resolveIdentity - Resolves authentication context to a Profile\n *\n * Used by apps (blindmanpress.com) to resolve incoming auth to a Profile.\n * Modules (aedile, praeco) should receive the resolved profile from the app.\n *\n * Resolution order:\n * 1. API key header → ApiKey → Profile\n * 2. OIDC session → OidcIdentity → Profile\n * 3. Nostr auth → NostrIdentity → Profile\n * 4. Actor header (CI pass-through) → Profile lookup\n */\n\nimport {\n resolveDatabase,\n type SmrtObjectOptions,\n} from '@happyvertical/smrt-core';\nimport { withSystemContext } from '@happyvertical/smrt-tenancy';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { ApiKey } from '../models/ApiKey';\nimport { NostrIdentity } from '../models/NostrIdentity';\nimport { OidcIdentity } from '../models/OidcIdentity';\nimport type { Profile } from '../models/Profile';\nimport { normalizeIdentityEmail } from './normalizeIdentityEmail';\nimport { type NostrEvent, verifyAuthEvent } from './nostrCrypto';\nimport {\n coordinateOidcProvisioning,\n isOidcProvisioningRaceConflict,\n} from './oidcProvisioningCoordinator';\nimport {\n createOidcProvisioningPerson,\n insertOidcProvisioningIdentity,\n} from './oidcProvisioningPrimitives';\n\n/**\n * Context provided to resolveIdentity\n */\nexport interface AuthContext {\n /**\n * API key from X-API-Key header or similar\n */\n apiKey?: string | null;\n\n /**\n * OIDC session data (from @auth/sveltekit or similar)\n */\n oidcSession?: {\n sub?: string;\n iss?: string;\n email?: string;\n name?: string;\n } | null;\n\n /**\n * Actor identifier for CI pass-through identity\n * Usually the GitHub actor (username) who triggered the workflow\n */\n actor?: string | null;\n\n /**\n * Nostr authentication data (NIP-42 style)\n */\n nostrAuth?: {\n /** Signed Nostr event for authentication */\n event: NostrEvent;\n /** Expected challenge (to prevent replay attacks) */\n challenge: string;\n } | null;\n\n /**\n * Database/persistence options\n */\n db?: SmrtObjectOptions['db'];\n}\n\n/**\n * Result of identity resolution\n */\nexport interface ResolveIdentityResult {\n /**\n * The resolved profile, or null if not authenticated\n */\n profile: Profile | null;\n\n /**\n * How the identity was resolved\n */\n source: 'api_key' | 'oidc' | 'nostr' | 'actor' | 'none';\n\n /**\n * The API key record if authenticated via API key\n */\n apiKey?: ApiKey;\n\n /**\n * The OIDC identity record if authenticated via OIDC\n */\n oidcIdentity?: OidcIdentity;\n\n /**\n * The Nostr identity record if authenticated via Nostr\n */\n nostrIdentity?: NostrIdentity;\n}\n\n/**\n * Resolve authentication context to a Profile\n *\n * @param context - The authentication context from the request\n * @returns The resolved profile and metadata\n *\n * @example\n * ```typescript\n * // In SvelteKit hooks.server.ts\n * import { resolveIdentity } from '@happyvertical/smrt-profiles';\n *\n * const identityMiddleware: Handle = async ({ event, resolve }) => {\n * const session = await event.locals.auth();\n *\n * const { profile, source } = await resolveIdentity({\n * oidcSession: session,\n * apiKey: event.request.headers.get('X-API-Key'),\n * actor: event.request.headers.get('X-Actor'),\n * db: { type: 'postgres', url: DATABASE_URL },\n * });\n *\n * event.locals.profile = profile;\n * event.locals.authSource = source;\n *\n * return resolve(event);\n * };\n * ```\n */\nexport async function resolveIdentity(\n context: AuthContext,\n): Promise<ResolveIdentityResult> {\n const options: SmrtObjectOptions = { db: context.db };\n\n // 1. Check API key header first (highest priority for programmatic access)\n if (context.apiKey) {\n const apiKey = await ApiKey.verify(context.apiKey, options);\n if (apiKey) {\n const profile = await apiKey.getProfile();\n if (profile) {\n return {\n profile,\n source: 'api_key',\n apiKey,\n };\n }\n }\n }\n\n // 2. Check OIDC session (web users)\n if (context.oidcSession?.sub && context.oidcSession?.iss) {\n const oidcIdentity = await OidcIdentity.findBySubject(\n context.oidcSession.iss,\n context.oidcSession.sub,\n options,\n );\n\n if (oidcIdentity) {\n // Record usage\n await oidcIdentity.recordUsage();\n\n const profile = await oidcIdentity.getProfile();\n if (profile) {\n return {\n profile,\n source: 'oidc',\n oidcIdentity,\n };\n }\n }\n }\n\n // 3. Check Nostr auth (NIP-42 style signed event)\n if (context.nostrAuth?.event && context.nostrAuth?.challenge) {\n const { event, challenge } = context.nostrAuth;\n\n // Verify the auth event\n const verifyResult = verifyAuthEvent(event, challenge);\n if (verifyResult.valid) {\n // Look up identity by public key\n const nostrIdentity = await NostrIdentity.findByPubkey(\n event.pubkey,\n options,\n );\n\n if (nostrIdentity) {\n // Record usage\n await nostrIdentity.recordUsage();\n\n const profile = await nostrIdentity.getProfile();\n if (profile) {\n return {\n profile,\n source: 'nostr',\n nostrIdentity,\n };\n }\n }\n }\n }\n\n // 4. Check actor for CI pass-through (look up by metadata)\n if (context.actor) {\n const profile = await findProfileByExternalId(\n 'github',\n context.actor,\n options,\n );\n if (profile) {\n return {\n profile,\n source: 'actor',\n };\n }\n }\n\n // No authentication found\n return {\n profile: null,\n source: 'none',\n };\n}\n\n/**\n * Find a profile by external ID (e.g., GitHub username)\n *\n * This looks up profiles by their linked external identities or metadata.\n *\n * @param provider - The external provider (e.g., 'github')\n * @param externalId - The external identifier (e.g., GitHub username)\n * @param options - Database options\n * @returns The profile or null\n */\nasync function findProfileByExternalId(\n provider: string,\n externalId: string,\n options: SmrtObjectOptions,\n): Promise<Profile | null> {\n // First check OIDC identities (if they use the provider)\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n\n const oidcCollection = await OidcIdentityCollection.create(options);\n const identities = await oidcCollection.findByProvider(provider);\n\n for (const identity of identities) {\n // Check if the subject matches the external ID\n if (\n identity.subject === externalId ||\n identity.email?.includes(externalId)\n ) {\n const profile = await identity.getProfile();\n if (profile) return profile;\n }\n }\n\n // Could also check profile metadata for external IDs\n // This would require a standardized metadata field like 'github_username'\n const { ProfileCollection } = await import(\n '../collections/ProfileCollection'\n );\n const profileCollection = await ProfileCollection.create(options);\n\n // Try to find by email that looks like a GitHub noreply\n const profiles = await profileCollection.list({\n where: {\n email: `${externalId}@users.noreply.github.com`,\n },\n limit: 1,\n });\n\n if (profiles.length > 0) {\n return profiles[0];\n }\n\n return null;\n}\n\n/**\n * Create a profile from OIDC claims if it doesn't exist\n *\n * Resolution order:\n * 1. If OIDC identity (iss + sub) already exists → return linked profile\n * 2. If the email matches an existing Profile, fail closed because this\n * package cannot prove whether a User owns it\n * 3. Otherwise, create new profile + identity\n *\n * Security considerations:\n * - Existing issuer/subject links always keep their already-linked Profile,\n * including legacy tenant-scoped or non-Person Profiles, and refresh the\n * cached identity email. This exact-link compatibility does not perform\n * email-based canonical reuse.\n * - New identities never attach to an existing email match through this\n * Profile-only helper because Profile ownership belongs to the users package.\n * Use `UserCollection.getOrCreateFromOidc()` for owner-aware verified-email\n * reuse and its supported pre-provision resolver hook.\n * - This function trusts the OIDC provider to assert correct email_verified status.\n * Only use with trusted providers.\n *\n * @param claims - OIDC token claims\n * @param provider - Provider name (e.g., 'keycloak', 'google', 'github')\n * @param options - Database options\n * @returns The created or existing profile with linked OIDC identity\n */\nexport async function createProfileFromOidc(\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions,\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: boolean }> {\n return coordinateProfileOidcProvisioning(claims, provider, options);\n}\n\n/**\n * @internal Transactionally reuse one exact legacy issuer/subject link.\n *\n * This path cannot create or rebind authority. It intentionally preserves\n * existing tenant-scoped and non-Person Profile links; canonical global Person\n * validation remains mandatory for every path that creates a User/session.\n */\nexport async function reuseExistingOidcIdentityForProfile(\n profileId: string,\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions,\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: false }> {\n const normalizedClaims = normalizeOidcProfileClaims(claims);\n const db = await resolveOidcProfileDatabase(options.db);\n return coordinateOidcProvisioning({\n db,\n lockKeys: [\n `identity:${OidcIdentity.buildIdentityKey(\n normalizedClaims.iss,\n normalizedClaims.sub,\n )}`,\n ],\n isRaceConflict: isOidcProvisioningRaceConflict,\n createTransactionError: (message, cause) =>\n new Error(message, cause === undefined ? undefined : { cause }),\n createConcurrencyError: (cause) =>\n new Error(\n 'Concurrent exact OIDC identity reuse did not converge.',\n cause === undefined ? undefined : { cause },\n ),\n rebindRootResult: rebindOidcProfileResult,\n provision: (tx) =>\n withSystemContext(async () => {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const identity = await (\n await OidcIdentityCollection.create({ db: tx })\n ).findBySubject(normalizedClaims.iss, normalizedClaims.sub);\n if (!identity) {\n throw new Error(\n 'OidcIdentity.findOrCreate() no longer creates authentication links; use UserCollection.getOrCreateFromOidc() or createProfileFromOidc().',\n );\n }\n if (identity.profileId !== profileId) {\n throw new Error(\n `OIDC identity ${normalizedClaims.iss} subject ${normalizedClaims.sub} belongs to a different Profile.`,\n );\n }\n const profile = await identity.getProfile();\n if (!profile) {\n throw new Error('The exact OIDC identity has no linked Profile.');\n }\n identity.provider = provider;\n if (normalizedClaims.email) identity.email = normalizedClaims.email;\n identity.lastUsedAt = new Date();\n await identity.save();\n return { profile, oidcIdentity: identity, created: false as const };\n }),\n });\n}\n\nasync function coordinateProfileOidcProvisioning(\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions,\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: boolean }> {\n const normalizedClaims = normalizeOidcProfileClaims(claims);\n const db = await resolveOidcProfileDatabase(options.db);\n return coordinateOidcProvisioning({\n db,\n lockKeys: [\n `identity:${OidcIdentity.buildIdentityKey(\n normalizedClaims.iss,\n normalizedClaims.sub,\n )}`,\n ...(normalizedClaims.email ? [`email:${normalizedClaims.email}`] : []),\n ],\n isRaceConflict: isOidcProvisioningRaceConflict,\n createTransactionError: (message, cause) =>\n new Error(message, cause === undefined ? undefined : { cause }),\n createConcurrencyError: (cause) =>\n new Error(\n 'Concurrent OIDC Profile provisioning did not converge.',\n cause === undefined ? undefined : { cause },\n ),\n rebindRootResult: rebindOidcProfileResult,\n provision: (tx) =>\n withSystemContext(() =>\n provisionOidcProfile(normalizedClaims, provider, {\n ...options,\n db: tx,\n }),\n ),\n });\n}\n\nasync function provisionOidcProfile(\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions & { db: DatabaseInterface },\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: boolean }> {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const identityCollection = await OidcIdentityCollection.create(options);\n const existingIdentity = await identityCollection.findBySubject(\n claims.iss,\n claims.sub,\n );\n if (existingIdentity) {\n const profile = await existingIdentity.getProfile();\n if (!profile) {\n throw new Error('The exact OIDC identity has no linked Profile.');\n }\n // `findBySubject()` normalizes the FK at this authentication boundary;\n // keep the related object on that portable identity as well for native\n // DuckDB adapters whose raw UUID values are represented as objects.\n profile.id = requireOidcProfileId(existingIdentity.profileId);\n if (claims.email) existingIdentity.email = claims.email;\n existingIdentity.lastUsedAt = new Date();\n await existingIdentity.save();\n return { profile, oidcIdentity: existingIdentity, created: false };\n }\n\n const { ProfileCollection } = await import(\n '../collections/ProfileCollection'\n );\n const profileCollection = await ProfileCollection.create(options);\n if (claims.email) {\n const collision = await profileCollection.findUniqueGlobalPersonByEmail(\n claims.email,\n );\n if (collision) {\n if (claims.email_verified !== true) {\n throw new Error(\n `OIDC email ${claims.email} is not verified and already belongs to a Profile.`,\n );\n }\n throw new Error(\n `OIDC email ${claims.email} already belongs to a Profile; createProfileFromOidc() cannot prove that Profile is unowned. Use UserCollection.getOrCreateFromOidc() for owner-aware linking.`,\n );\n }\n }\n\n const profile = await createOidcProvisioningPerson(options.db, {\n email: claims.email ?? '',\n name: claims.name,\n preferredUsername: claims.preferred_username,\n subject: claims.sub,\n });\n const oidcIdentity = await insertOidcProvisioningIdentity(options.db, {\n email: claims.email,\n issuer: claims.iss,\n profileId: requireOidcProfileId(profile.id),\n provider,\n subject: claims.sub,\n });\n return { profile, oidcIdentity, created: true };\n}\n\nasync function rebindOidcProfileResult<\n T extends {\n profile: Profile;\n oidcIdentity: OidcIdentity;\n created: boolean;\n },\n>(result: T, rootDb: DatabaseInterface): Promise<T> {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const { ProfileCollection } = await import(\n '../collections/ProfileCollection'\n );\n const profileId = requireOidcProfileId(result.profile.id);\n const identityId = requireOidcProfileId(result.oidcIdentity.id);\n const [profile, oidcIdentity] = await withSystemContext(async () => {\n const profiles = await ProfileCollection.create({ db: rootDb });\n const identities = await OidcIdentityCollection.create({ db: rootDb });\n // Read one statement at a time. SQLite and DuckDB handles multiplex a\n // single native connection, so overlapping statements on it fail the\n // losing prepared statement or abort the process outright (#2352). These\n // are primary-key reads, so the sequential cost is one extra round trip.\n const rebound = await profiles.get({ id: profileId });\n const reboundIdentity = await identities.get({ id: identityId });\n return [rebound, reboundIdentity] as const;\n });\n if (!profile || !oidcIdentity) {\n throw new Error(\n 'Committed OIDC Profile provisioning result was not found.',\n );\n }\n profile.id = profileId;\n oidcIdentity.id = identityId;\n oidcIdentity.profileId = profileId;\n return { ...result, profile, oidcIdentity };\n}\n\nfunction normalizeOidcProfileClaims(claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n}) {\n const sub = claims?.sub;\n const iss = claims?.iss;\n if (\n typeof sub !== 'string' ||\n sub.trim().length === 0 ||\n typeof iss !== 'string' ||\n iss.trim().length === 0\n ) {\n throw new Error(\n 'Invalid OIDC claims: both \"sub\" and \"iss\" must be non-empty strings.',\n );\n }\n const suppliedEmail = claims.email;\n return {\n ...claims,\n sub,\n iss,\n email:\n typeof suppliedEmail === 'string' && suppliedEmail.trim()\n ? normalizeIdentityEmail(suppliedEmail)\n : undefined,\n };\n}\n\nfunction requireOidcProfileId(value: unknown): string {\n if (typeof value !== 'string' || !value) {\n throw new Error('OIDC Profile provisioning did not produce an id.');\n }\n return value;\n}\n\nasync function resolveOidcProfileDatabase(\n db: SmrtObjectOptions['db'],\n): Promise<DatabaseInterface> {\n if (!db) {\n throw new Error(\n 'OIDC Profile provisioning requires an initialized database.',\n );\n }\n return resolveDatabase(db as Parameters<typeof resolveDatabase>[0]);\n}\n\n/**\n * Create a profile from Nostr identity (used by magic link service)\n *\n * This is typically called internally by the magic link service,\n * but can be used directly if needed.\n *\n * @param email - Email address for the profile\n * @param nostrData - Encrypted Nostr keypair data\n * @param options - Database options\n * @returns The created profile with linked Nostr identity\n */\nexport async function createProfileFromNostr(\n email: string,\n nostrData: {\n pubkey: string;\n encryptedPrivkey: string;\n encryptionIv: string;\n encryptionTag: string;\n nip05Username?: string;\n },\n options: SmrtObjectOptions,\n): Promise<{\n profile: Profile;\n nostrIdentity: NostrIdentity;\n created: boolean;\n}> {\n const normalizedEmail = normalizeIdentityEmail(email);\n\n // Check if Nostr identity already exists\n const existingIdentity = await NostrIdentity.findByEmail(\n normalizedEmail,\n options,\n );\n\n if (existingIdentity) {\n const profile = await existingIdentity.getProfile();\n if (profile) {\n return {\n profile,\n nostrIdentity: existingIdentity,\n created: false,\n };\n }\n }\n\n // Create new profile\n const { Person } = await import('../models/ProfileTypes');\n const { ProfileTypeCollection } = await import(\n '../collections/ProfileTypeCollection'\n );\n\n // Get or create the 'person' type\n const typeCollection = await ProfileTypeCollection.create(options);\n let personType = await typeCollection.getBySlug('person');\n\n if (!personType) {\n const { ProfileType } = await import('../models/ProfileType');\n personType = new ProfileType({\n ...options,\n slug: 'person',\n name: 'Person',\n description: 'Individual person profile',\n });\n await personType.initialize();\n await personType.save();\n }\n\n const profile = new Person({\n ...options,\n typeId: personType.id as string,\n email: normalizedEmail,\n name: normalizedEmail.split('@')[0], // Default name from email\n });\n await profile.initialize();\n await profile.save();\n\n // Create Nostr identity\n const nostrIdentity = new NostrIdentity({\n ...options,\n profileId: profile.id as string,\n pubkey: nostrData.pubkey,\n encryptedPrivkey: nostrData.encryptedPrivkey,\n encryptionIv: nostrData.encryptionIv,\n encryptionTag: nostrData.encryptionTag,\n email: normalizedEmail,\n nip05Username:\n nostrData.nip05Username?.toLowerCase() || normalizedEmail.split('@')[0],\n });\n await nostrIdentity.initialize();\n await nostrIdentity.save();\n\n return {\n profile,\n nostrIdentity,\n created: true,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolveIdentity-CvGDegU6.js","names":["profile"],"sources":["../../src/auth/resolveIdentity.ts"],"sourcesContent":["/**\n * resolveIdentity - Resolves authentication context to a Profile\n *\n * Used by apps (blindmanpress.com) to resolve incoming auth to a Profile.\n * Modules (aedile, praeco) should receive the resolved profile from the app.\n *\n * Resolution order:\n * 1. API key header → ApiKey → Profile\n * 2. OIDC session → OidcIdentity → Profile\n * 3. Nostr auth → NostrIdentity → Profile\n * 4. Actor header (CI pass-through) → Profile lookup\n */\n\nimport {\n resolveDatabase,\n type SmrtObjectOptions,\n} from '@happyvertical/smrt-core';\nimport { withSystemContext } from '@happyvertical/smrt-tenancy';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { ApiKey } from '../models/ApiKey';\nimport { NostrIdentity } from '../models/NostrIdentity';\nimport { OidcIdentity } from '../models/OidcIdentity';\nimport type { Profile } from '../models/Profile';\nimport { normalizeIdentityEmail } from './normalizeIdentityEmail';\nimport { type NostrEvent, verifyAuthEvent } from './nostrCrypto';\nimport {\n coordinateOidcProvisioning,\n isOidcProvisioningRaceConflict,\n} from './oidcProvisioningCoordinator';\nimport {\n createOidcProvisioningPerson,\n insertOidcProvisioningIdentity,\n} from './oidcProvisioningPrimitives';\n\n/**\n * Context provided to resolveIdentity\n */\nexport interface AuthContext {\n /**\n * API key from X-API-Key header or similar\n */\n apiKey?: string | null;\n\n /**\n * OIDC session data (from @auth/sveltekit or similar)\n */\n oidcSession?: {\n sub?: string;\n iss?: string;\n email?: string;\n name?: string;\n } | null;\n\n /**\n * Actor identifier for CI pass-through identity\n * Usually the GitHub actor (username) who triggered the workflow\n */\n actor?: string | null;\n\n /**\n * Nostr authentication data (NIP-42 style)\n */\n nostrAuth?: {\n /** Signed Nostr event for authentication */\n event: NostrEvent;\n /** Expected challenge (to prevent replay attacks) */\n challenge: string;\n } | null;\n\n /**\n * Database/persistence options\n */\n db?: SmrtObjectOptions['db'];\n}\n\n/**\n * Result of identity resolution\n */\nexport interface ResolveIdentityResult {\n /**\n * The resolved profile, or null if not authenticated\n */\n profile: Profile | null;\n\n /**\n * How the identity was resolved\n */\n source: 'api_key' | 'oidc' | 'nostr' | 'actor' | 'none';\n\n /**\n * The API key record if authenticated via API key\n */\n apiKey?: ApiKey;\n\n /**\n * The OIDC identity record if authenticated via OIDC\n */\n oidcIdentity?: OidcIdentity;\n\n /**\n * The Nostr identity record if authenticated via Nostr\n */\n nostrIdentity?: NostrIdentity;\n}\n\n/**\n * Resolve authentication context to a Profile\n *\n * @param context - The authentication context from the request\n * @returns The resolved profile and metadata\n *\n * @example\n * ```typescript\n * // In SvelteKit hooks.server.ts\n * import { resolveIdentity } from '@happyvertical/smrt-profiles';\n *\n * const identityMiddleware: Handle = async ({ event, resolve }) => {\n * const session = await event.locals.auth();\n *\n * const { profile, source } = await resolveIdentity({\n * oidcSession: session,\n * apiKey: event.request.headers.get('X-API-Key'),\n * actor: event.request.headers.get('X-Actor'),\n * db: { type: 'postgres', url: DATABASE_URL },\n * });\n *\n * event.locals.profile = profile;\n * event.locals.authSource = source;\n *\n * return resolve(event);\n * };\n * ```\n */\nexport async function resolveIdentity(\n context: AuthContext,\n): Promise<ResolveIdentityResult> {\n const options: SmrtObjectOptions = { db: context.db };\n\n // 1. Check API key header first (highest priority for programmatic access)\n if (context.apiKey) {\n const apiKey = await ApiKey.verify(context.apiKey, options);\n if (apiKey) {\n const profile = await apiKey.getProfile();\n if (profile) {\n return {\n profile,\n source: 'api_key',\n apiKey,\n };\n }\n }\n }\n\n // 2. Check OIDC session (web users)\n if (context.oidcSession?.sub && context.oidcSession?.iss) {\n const oidcIdentity = await OidcIdentity.findBySubject(\n context.oidcSession.iss,\n context.oidcSession.sub,\n options,\n );\n\n if (oidcIdentity) {\n // Record usage\n await oidcIdentity.recordUsage();\n\n const profile = await oidcIdentity.getProfile();\n if (profile) {\n return {\n profile,\n source: 'oidc',\n oidcIdentity,\n };\n }\n }\n }\n\n // 3. Check Nostr auth (NIP-42 style signed event)\n if (context.nostrAuth?.event && context.nostrAuth?.challenge) {\n const { event, challenge } = context.nostrAuth;\n\n // Verify the auth event\n const verifyResult = verifyAuthEvent(event, challenge);\n if (verifyResult.valid) {\n // Look up identity by public key\n const nostrIdentity = await NostrIdentity.findByPubkey(\n event.pubkey,\n options,\n );\n\n if (nostrIdentity) {\n // Record usage\n await nostrIdentity.recordUsage();\n\n const profile = await nostrIdentity.getProfile();\n if (profile) {\n return {\n profile,\n source: 'nostr',\n nostrIdentity,\n };\n }\n }\n }\n }\n\n // 4. Check actor for CI pass-through (look up by metadata)\n if (context.actor) {\n const profile = await findProfileByExternalId(\n 'github',\n context.actor,\n options,\n );\n if (profile) {\n return {\n profile,\n source: 'actor',\n };\n }\n }\n\n // No authentication found\n return {\n profile: null,\n source: 'none',\n };\n}\n\n/**\n * Find a profile by external ID (e.g., GitHub username)\n *\n * This looks up profiles by their linked external identities or metadata.\n *\n * @param provider - The external provider (e.g., 'github')\n * @param externalId - The external identifier (e.g., GitHub username)\n * @param options - Database options\n * @returns The profile or null\n */\nasync function findProfileByExternalId(\n provider: string,\n externalId: string,\n options: SmrtObjectOptions,\n): Promise<Profile | null> {\n // First check OIDC identities (if they use the provider)\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n\n const oidcCollection = await OidcIdentityCollection.create(options);\n const identities = await oidcCollection.findByProvider(provider);\n\n for (const identity of identities) {\n // Check if the subject matches the external ID\n if (\n identity.subject === externalId ||\n identity.email?.includes(externalId)\n ) {\n const profile = await identity.getProfile();\n if (profile) return profile;\n }\n }\n\n // Could also check profile metadata for external IDs\n // This would require a standardized metadata field like 'github_username'\n const { ProfileCollection } = await import(\n '../collections/ProfileCollection'\n );\n const profileCollection = await ProfileCollection.create(options);\n\n // Try to find by email that looks like a GitHub noreply\n const profiles = await profileCollection.list({\n where: {\n email: `${externalId}@users.noreply.github.com`,\n },\n limit: 1,\n });\n\n if (profiles.length > 0) {\n return profiles[0];\n }\n\n return null;\n}\n\n/**\n * Create a profile from OIDC claims if it doesn't exist\n *\n * Resolution order:\n * 1. If OIDC identity (iss + sub) already exists → return linked profile\n * 2. If the email matches an existing Profile, fail closed because this\n * package cannot prove whether a User owns it\n * 3. Otherwise, create new profile + identity\n *\n * Security considerations:\n * - Existing issuer/subject links always keep their already-linked Profile,\n * including legacy tenant-scoped or non-Person Profiles, and refresh the\n * cached identity email. This exact-link compatibility does not perform\n * email-based canonical reuse.\n * - New identities never attach to an existing email match through this\n * Profile-only helper because Profile ownership belongs to the users package.\n * Use `UserCollection.getOrCreateFromOidc()` for owner-aware verified-email\n * reuse and its supported pre-provision resolver hook.\n * - This function trusts the OIDC provider to assert correct email_verified status.\n * Only use with trusted providers.\n *\n * @param claims - OIDC token claims\n * @param provider - Provider name (e.g., 'keycloak', 'google', 'github')\n * @param options - Database options\n * @returns The created or existing profile with linked OIDC identity\n */\nexport async function createProfileFromOidc(\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions,\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: boolean }> {\n return coordinateProfileOidcProvisioning(claims, provider, options);\n}\n\n/**\n * @internal Transactionally reuse one exact legacy issuer/subject link.\n *\n * This path cannot create or rebind authority. It intentionally preserves\n * existing tenant-scoped and non-Person Profile links; canonical global Person\n * validation remains mandatory for every path that creates a User/session.\n */\nexport async function reuseExistingOidcIdentityForProfile(\n profileId: string,\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions,\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: false }> {\n const normalizedClaims = normalizeOidcProfileClaims(claims);\n const db = await resolveOidcProfileDatabase(options.db);\n return coordinateOidcProvisioning({\n db,\n lockKeys: [\n `identity:${OidcIdentity.buildIdentityKey(\n normalizedClaims.iss,\n normalizedClaims.sub,\n )}`,\n ],\n isRaceConflict: isOidcProvisioningRaceConflict,\n createTransactionError: (message, cause) =>\n new Error(message, cause === undefined ? undefined : { cause }),\n createConcurrencyError: (cause) =>\n new Error(\n 'Concurrent exact OIDC identity reuse did not converge.',\n cause === undefined ? undefined : { cause },\n ),\n rebindRootResult: rebindOidcProfileResult,\n provision: (tx) =>\n withSystemContext(async () => {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const identity = await (\n await OidcIdentityCollection.create({ db: tx })\n ).findBySubject(normalizedClaims.iss, normalizedClaims.sub);\n if (!identity) {\n throw new Error(\n 'OidcIdentity.findOrCreate() no longer creates authentication links; use UserCollection.getOrCreateFromOidc() or createProfileFromOidc().',\n );\n }\n if (identity.profileId !== profileId) {\n throw new Error(\n `OIDC identity ${normalizedClaims.iss} subject ${normalizedClaims.sub} belongs to a different Profile.`,\n );\n }\n const profile = await identity.getProfile();\n if (!profile) {\n throw new Error('The exact OIDC identity has no linked Profile.');\n }\n identity.provider = provider;\n if (normalizedClaims.email) identity.email = normalizedClaims.email;\n identity.lastUsedAt = new Date();\n await identity.save();\n return { profile, oidcIdentity: identity, created: false as const };\n }),\n });\n}\n\nasync function coordinateProfileOidcProvisioning(\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions,\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: boolean }> {\n const normalizedClaims = normalizeOidcProfileClaims(claims);\n const db = await resolveOidcProfileDatabase(options.db);\n return coordinateOidcProvisioning({\n db,\n lockKeys: [\n `identity:${OidcIdentity.buildIdentityKey(\n normalizedClaims.iss,\n normalizedClaims.sub,\n )}`,\n ...(normalizedClaims.email ? [`email:${normalizedClaims.email}`] : []),\n ],\n isRaceConflict: isOidcProvisioningRaceConflict,\n createTransactionError: (message, cause) =>\n new Error(message, cause === undefined ? undefined : { cause }),\n createConcurrencyError: (cause) =>\n new Error(\n 'Concurrent OIDC Profile provisioning did not converge.',\n cause === undefined ? undefined : { cause },\n ),\n rebindRootResult: rebindOidcProfileResult,\n provision: (tx) =>\n withSystemContext(() =>\n provisionOidcProfile(normalizedClaims, provider, {\n ...options,\n db: tx,\n }),\n ),\n });\n}\n\nasync function provisionOidcProfile(\n claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n },\n provider: string,\n options: SmrtObjectOptions & { db: DatabaseInterface },\n): Promise<{ profile: Profile; oidcIdentity: OidcIdentity; created: boolean }> {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const identityCollection = await OidcIdentityCollection.create(options);\n const existingIdentity = await identityCollection.findBySubject(\n claims.iss,\n claims.sub,\n );\n if (existingIdentity) {\n const profile = await existingIdentity.getProfile();\n if (!profile) {\n throw new Error('The exact OIDC identity has no linked Profile.');\n }\n // `findBySubject()` normalizes the FK at this authentication boundary;\n // keep the related object on that portable identity as well for native\n // DuckDB adapters whose raw UUID values are represented as objects.\n profile.id = requireOidcProfileId(existingIdentity.profileId);\n if (claims.email) existingIdentity.email = claims.email;\n existingIdentity.lastUsedAt = new Date();\n await existingIdentity.save();\n return { profile, oidcIdentity: existingIdentity, created: false };\n }\n\n const { ProfileCollection } = await import(\n '../collections/ProfileCollection'\n );\n const profileCollection = await ProfileCollection.create(options);\n if (claims.email) {\n const collision = await profileCollection.findUniqueGlobalPersonByEmail(\n claims.email,\n );\n if (collision) {\n if (claims.email_verified !== true) {\n throw new Error(\n `OIDC email ${claims.email} is not verified and already belongs to a Profile.`,\n );\n }\n throw new Error(\n `OIDC email ${claims.email} already belongs to a Profile; createProfileFromOidc() cannot prove that Profile is unowned. Use UserCollection.getOrCreateFromOidc() for owner-aware linking.`,\n );\n }\n }\n\n const profile = await createOidcProvisioningPerson(options.db, {\n email: claims.email ?? '',\n name: claims.name,\n preferredUsername: claims.preferred_username,\n subject: claims.sub,\n });\n const oidcIdentity = await insertOidcProvisioningIdentity(options.db, {\n email: claims.email,\n issuer: claims.iss,\n profileId: requireOidcProfileId(profile.id),\n provider,\n subject: claims.sub,\n });\n return { profile, oidcIdentity, created: true };\n}\n\nasync function rebindOidcProfileResult<\n T extends {\n profile: Profile;\n oidcIdentity: OidcIdentity;\n created: boolean;\n },\n>(result: T, rootDb: DatabaseInterface): Promise<T> {\n const { OidcIdentityCollection } = await import(\n '../collections/OidcIdentityCollection'\n );\n const { ProfileCollection } = await import(\n '../collections/ProfileCollection'\n );\n const profileId = requireOidcProfileId(result.profile.id);\n const identityId = requireOidcProfileId(result.oidcIdentity.id);\n const [profile, oidcIdentity] = await withSystemContext(async () => {\n const profiles = await ProfileCollection.create({ db: rootDb });\n const identities = await OidcIdentityCollection.create({ db: rootDb });\n // Read one statement at a time. SQLite and DuckDB handles multiplex a\n // single native connection, so overlapping statements on it fail the\n // losing prepared statement or abort the process outright (#2352). These\n // are primary-key reads, so the sequential cost is one extra round trip.\n const rebound = await profiles.get({ id: profileId });\n const reboundIdentity = await identities.get({ id: identityId });\n return [rebound, reboundIdentity] as const;\n });\n if (!profile || !oidcIdentity) {\n throw new Error(\n 'Committed OIDC Profile provisioning result was not found.',\n );\n }\n profile.id = profileId;\n oidcIdentity.id = identityId;\n oidcIdentity.profileId = profileId;\n return { ...result, profile, oidcIdentity };\n}\n\nfunction normalizeOidcProfileClaims(claims: {\n sub: string;\n iss: string;\n email?: string;\n email_verified?: boolean;\n name?: string;\n preferred_username?: string;\n}) {\n const sub = claims?.sub;\n const iss = claims?.iss;\n if (\n typeof sub !== 'string' ||\n sub.trim().length === 0 ||\n typeof iss !== 'string' ||\n iss.trim().length === 0\n ) {\n throw new Error(\n 'Invalid OIDC claims: both \"sub\" and \"iss\" must be non-empty strings.',\n );\n }\n const suppliedEmail = claims.email;\n return {\n ...claims,\n sub,\n iss,\n email:\n typeof suppliedEmail === 'string' && suppliedEmail.trim()\n ? normalizeIdentityEmail(suppliedEmail)\n : undefined,\n };\n}\n\nfunction requireOidcProfileId(value: unknown): string {\n if (typeof value !== 'string' || !value) {\n throw new Error('OIDC Profile provisioning did not produce an id.');\n }\n return value;\n}\n\nasync function resolveOidcProfileDatabase(\n db: SmrtObjectOptions['db'],\n): Promise<DatabaseInterface> {\n if (!db) {\n throw new Error(\n 'OIDC Profile provisioning requires an initialized database.',\n );\n }\n return resolveDatabase(db as Parameters<typeof resolveDatabase>[0]);\n}\n\n/**\n * Create a profile from Nostr identity (used by magic link service)\n *\n * This is typically called internally by the magic link service,\n * but can be used directly if needed.\n *\n * @param email - Email address for the profile\n * @param nostrData - Encrypted Nostr keypair data\n * @param options - Database options\n * @returns The created profile with linked Nostr identity\n */\nexport async function createProfileFromNostr(\n email: string,\n nostrData: {\n pubkey: string;\n encryptedPrivkey: string;\n encryptionIv: string;\n encryptionTag: string;\n nip05Username?: string;\n },\n options: SmrtObjectOptions,\n): Promise<{\n profile: Profile;\n nostrIdentity: NostrIdentity;\n created: boolean;\n}> {\n const normalizedEmail = normalizeIdentityEmail(email);\n\n // Check if Nostr identity already exists\n const existingIdentity = await NostrIdentity.findByEmail(\n normalizedEmail,\n options,\n );\n\n if (existingIdentity) {\n const profile = await existingIdentity.getProfile();\n if (profile) {\n return {\n profile,\n nostrIdentity: existingIdentity,\n created: false,\n };\n }\n }\n\n // Create new profile\n const { Person } = await import('../models/ProfileTypes');\n const { ProfileTypeCollection } = await import(\n '../collections/ProfileTypeCollection'\n );\n\n // Get or create the 'person' type\n const typeCollection = await ProfileTypeCollection.create(options);\n let personType = await typeCollection.getBySlug('person');\n\n if (!personType) {\n const { ProfileType } = await import('../models/ProfileType');\n personType = new ProfileType({\n ...options,\n slug: 'person',\n name: 'Person',\n description: 'Individual person profile',\n });\n await personType.initialize();\n await personType.save();\n }\n\n const profile = new Person({\n ...options,\n typeId: personType.id as string,\n email: normalizedEmail,\n name: normalizedEmail.split('@')[0], // Default name from email\n });\n await profile.initialize();\n await profile.save();\n\n // Create Nostr identity\n const nostrIdentity = new NostrIdentity({\n ...options,\n profileId: profile.id as string,\n pubkey: nostrData.pubkey,\n encryptedPrivkey: nostrData.encryptedPrivkey,\n encryptionIv: nostrData.encryptionIv,\n encryptionTag: nostrData.encryptionTag,\n email: normalizedEmail,\n nip05Username:\n nostrData.nip05Username?.toLowerCase() || normalizedEmail.split('@')[0],\n });\n await nostrIdentity.initialize();\n await nostrIdentity.save();\n\n return {\n profile,\n nostrIdentity,\n created: true,\n };\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AuditLogCollection - Collection for querying audit logs
3
3
  */
4
- import { SmrtCollection } from '@happyvertical/smrt-core';
4
+ import { type AuditChange, SmrtCollection } from '@happyvertical/smrt-core';
5
5
  import { AuditLog, type AuditSource } from '../models/AuditLog';
6
6
  import type { Profile } from '../models/Profile';
7
7
  export declare class AuditLogCollection extends SmrtCollection<AuditLog> {
@@ -37,6 +37,8 @@ export declare class AuditLogCollection extends SmrtCollection<AuditLog> {
37
37
  source?: AuditSource;
38
38
  metadata?: Record<string, unknown>;
39
39
  onBehalfOf?: Profile | null;
40
+ reason?: string;
41
+ changes?: Record<string, AuditChange>;
40
42
  }): Promise<AuditLog>;
41
43
  /**
42
44
  * Get recent activity for a profile
@@ -1 +1 @@
1
- {"version":3,"file":"AuditLogCollection.d.ts","sourceRoot":"","sources":["../../src/collections/AuditLogCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,qBAAa,kBAAmB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,kBAAY;IAEtC;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO3D;;OAEG;IACG,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOtB;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOvD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO5D;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO5D;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KAC7B,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgBrB;;OAEG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAQtB;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;CAMvB"}
1
+ {"version":3,"file":"AuditLogCollection.d.ts","sourceRoot":"","sources":["../../src/collections/AuditLogCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,qBAAa,kBAAmB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,kBAAY;IAEtC;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO3D;;OAEG;IACG,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOtB;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOvD;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO5D;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO5D;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;KACvC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAkBrB;;OAEG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAQtB;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,EAAE,CAAC;CAMvB"}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@
9
9
  import './__smrt-register__.js';
10
10
  import './prompts.js';
11
11
  export { AGENT_PROFILE_CONTEXT, AGENT_PROFILE_TYPE_SLUG, type ResolveAgentProfileParams, resolveAgentProfile, resolveAgentProfileId, } from './agent-profile';
12
+ export * from './audit-trail.js';
12
13
  export { type AuthContext, computeEventId, createAuthEvent, createMagicLinkService, createNip05Handler, createProfileFromNostr, createProfileFromOidc, decryptPrivkey, deriveEncryptionKey, type EncryptedKey, encryptPrivkey, generateNostrKeypair, getPublicKey, type InitiateResult, isValidNip05Identifier, isValidPrivkey, isValidPubkey, type MagicLinkConfig, type MagicLinkService, type Nip05HandlerConfig, type Nip05HandlerResult, type Nip05Request, type NostrEvent, type NostrKeypair, normalizeIdentityEmail, npubToPubkey, nsecToPrivkey, parseNip05Identifier, privkeyToNsec, pubkeyToNpub, type ResolveIdentityResult, resolveIdentity, signEvent, type VerifyResult, verifyAuthEvent, verifyNostrSignature, } from './auth';
13
14
  export { ApiKeyCollection } from './collections/ApiKeyCollection';
14
15
  export { AuditLogCollection } from './collections/AuditLogCollection';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}