@undefineds.co/xpod 0.3.44 → 0.3.45

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.
@@ -46,18 +46,6 @@ function stableUuid(input) {
46
46
  hex.slice(20, 32),
47
47
  ].join('-');
48
48
  }
49
- function inferIssuerFromWebId(webId) {
50
- if (!webId) {
51
- return undefined;
52
- }
53
- try {
54
- const url = new URL(webId);
55
- return `${url.origin}/`;
56
- }
57
- catch {
58
- return undefined;
59
- }
60
- }
61
49
  function buildWebIdFromIssuer(oidcIssuer, podName) {
62
50
  if (!oidcIssuer) {
63
51
  return undefined;
@@ -113,7 +101,9 @@ class LocalPodProvisioningService {
113
101
  async createPod(input) {
114
102
  const podUrl = ensureTrailingSlash(new URL(`${encodeURIComponent(input.podName)}/`, this.baseUrl).toString());
115
103
  const webId = input.webId ?? buildWebIdFromIssuer(this.oidcIssuer, input.podName) ?? `${podUrl}profile/card#me`;
116
- const oidcIssuer = this.oidcIssuer ?? inferIssuerFromWebId(webId) ?? this.baseUrl;
104
+ // Local storage resources are protected by the Local SP issuer even when
105
+ // their owner WebID is a Cloud identity.
106
+ const oidcIssuer = this.baseUrl;
117
107
  const accountId = stableUuid(`account:${podUrl}:${webId}`);
118
108
  const podId = stableUuid(`pod:${podUrl}:${webId}`);
119
109
  const ownerId = stableUuid(`owner:${podId}:${webId}`);
@@ -238,6 +228,7 @@ class LocalPodProvisioningService {
238
228
  out.push(quad(namedNode(cardUrl), namedNode(`${FOAF}primaryTopic`), namedNode(webId), cardGraph));
239
229
  out.push(quad(namedNode(webId), namedNode(`${RDF}type`), namedNode(`${FOAF}Person`), cardGraph));
240
230
  out.push(quad(namedNode(webId), namedNode(`${SOLID}oidcIssuer`), namedNode(oidcIssuer), cardGraph));
231
+ out.push(quad(namedNode(webId), namedNode(`${SOLID}storage`), namedNode(podUrl), cardGraph));
241
232
  out.push(...authorizationResources.quads);
242
233
  return out;
243
234
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LocalPodProvisioningService.js","sourceRoot":"","sources":["../../src/provision/LocalPodProvisioningService.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { DataFactory } from 'n3';\nimport type { Quad } from '@rdfjs/types';\nimport { getLoggerFor } from 'global-logger-factory';\nimport { quadToRow } from '../storage/quint/serialization';\nimport { getSqliteRuntime, type SqliteDatabase } from '../storage/SqliteRuntime';\nimport type { AuthMode } from '../authorization/AuthMode';\nimport { buildPodAuthorizationResources } from '../authorization/PodAuthorizationResources';\nimport { RdfQuadIndex } from '../storage/rdf/RdfQuadIndex';\n\nconst RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';\nconst LDP = 'http://www.w3.org/ns/ldp#';\nconst DCT = 'http://purl.org/dc/terms/';\nconst MA = 'http://www.w3.org/ns/ma-ont#';\nconst PIM = 'http://www.w3.org/ns/pim/space#';\nconst FOAF = 'http://xmlns.com/foaf/0.1/';\nconst SOLID = 'http://www.w3.org/ns/solid/terms#';\n\nconst { literal, namedNode, quad } = DataFactory;\n\nexport interface LocalPodProvisioningInput {\n podName: string;\n webId?: string;\n initialResources?: Record<string, string>;\n}\n\nexport interface LocalPodProvisioningResult {\n podUrl: string;\n accountId: string;\n podId: string;\n}\n\nexport interface LocalPodProvisioningServiceOptions {\n baseUrl: string;\n rootDir: string;\n sparqlEndpoint: string;\n identityDbUrl: string;\n rdfIndexPath?: string;\n oidcIssuer?: string;\n authMode?: AuthMode | string;\n}\n\nfunction ensureTrailingSlash(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nfunction stripSqlitePrefix(value: string, label: string): string {\n if (value.startsWith('sqlite:')) {\n return value.slice('sqlite:'.length);\n }\n if (value === ':memory:') {\n return value;\n }\n if (/^[a-z][a-z0-9+.-]*:/iu.test(value)) {\n throw new Error(`${label} must be a sqlite URL for local Pod provisioning: ${value}`);\n }\n return value;\n}\n\nfunction stableUuid(input: string): string {\n const hex = createHash('sha256').update(input).digest('hex').slice(0, 32);\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n `4${hex.slice(13, 16)}`,\n `${((Number.parseInt(hex.slice(16, 18), 16) & 0x3f) | 0x80).toString(16).padStart(2, '0')}${hex.slice(18, 20)}`,\n hex.slice(20, 32),\n ].join('-');\n}\n\nfunction inferIssuerFromWebId(webId: string | undefined): string | undefined {\n if (!webId) {\n return undefined;\n }\n try {\n const url = new URL(webId);\n return `${url.origin}/`;\n } catch {\n return undefined;\n }\n}\n\nfunction buildWebIdFromIssuer(oidcIssuer: string | undefined, podName: string): string | undefined {\n if (!oidcIssuer) {\n return undefined;\n }\n return new URL(`${encodeURIComponent(podName)}/profile/card#me`, ensureTrailingSlash(oidcIssuer)).toString();\n}\n\nfunction createQuintsTable(db: SqliteDatabase): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS quints (\n graph TEXT NOT NULL,\n subject TEXT NOT NULL,\n predicate TEXT NOT NULL,\n object TEXT NOT NULL,\n vector TEXT,\n PRIMARY KEY (graph, subject, predicate, object)\n );\n\n CREATE INDEX IF NOT EXISTS idx_spog ON quints (subject, predicate, object, graph);\n CREATE INDEX IF NOT EXISTS idx_ogsp ON quints (object, graph, subject, predicate);\n CREATE INDEX IF NOT EXISTS idx_gspo ON quints (graph, subject, predicate, object);\n CREATE INDEX IF NOT EXISTS idx_sopg ON quints (subject, object, predicate, graph);\n CREATE INDEX IF NOT EXISTS idx_pogs ON quints (predicate, object, graph, subject);\n CREATE INDEX IF NOT EXISTS idx_gpos ON quints (graph, predicate, object, subject);\n `);\n}\n\nfunction createInternalKvTable(db: SqliteDatabase): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS internal_kv (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n `);\n}\n\nfunction meta(resource: string): string {\n return `meta:${resource}`;\n}\n\nfunction iri(base: string, relative: string): string {\n return new URL(relative, base).toString();\n}\n\nexport class LocalPodProvisioningService {\n private readonly logger = getLoggerFor(this);\n private readonly baseUrl: string;\n private readonly rootDir: string;\n private readonly sparqlDbPath: string;\n private readonly identityDbPath: string;\n private readonly rdfIndexPath?: string;\n private readonly oidcIssuer?: string;\n private readonly authMode?: AuthMode | string;\n private readonly sqliteRuntime = getSqliteRuntime();\n\n public constructor(options: LocalPodProvisioningServiceOptions) {\n this.baseUrl = ensureTrailingSlash(options.baseUrl);\n this.rootDir = options.rootDir;\n this.sparqlDbPath = stripSqlitePrefix(options.sparqlEndpoint, 'sparqlEndpoint');\n this.identityDbPath = stripSqlitePrefix(options.identityDbUrl, 'identityDbUrl');\n this.rdfIndexPath = options.rdfIndexPath;\n this.oidcIssuer = options.oidcIssuer ? ensureTrailingSlash(options.oidcIssuer) : undefined;\n this.authMode = options.authMode;\n }\n\n public async createPod(input: LocalPodProvisioningInput): Promise<LocalPodProvisioningResult> {\n const podUrl = ensureTrailingSlash(new URL(`${encodeURIComponent(input.podName)}/`, this.baseUrl).toString());\n const webId = input.webId ?? buildWebIdFromIssuer(this.oidcIssuer, input.podName) ?? `${podUrl}profile/card#me`;\n const oidcIssuer = this.oidcIssuer ?? inferIssuerFromWebId(webId) ?? this.baseUrl;\n const accountId = stableUuid(`account:${podUrl}:${webId}`);\n const podId = stableUuid(`pod:${podUrl}:${webId}`);\n const ownerId = stableUuid(`owner:${podId}:${webId}`);\n const webIdLinkId = stableUuid(`webIdLink:${accountId}:${webId}`);\n\n await this.createPodFiles(input.podName, input.initialResources);\n const quads = this.buildPodQuads({ podUrl, webId, oidcIssuer });\n this.writeQuints(quads);\n this.writeRdfIndex(quads);\n this.writeIdentityIndexes({ accountId, podId, ownerId, webIdLinkId, podUrl, webId });\n\n this.logger.info(`Provisioned local pod ${podUrl} for ${webId}`);\n return { podUrl, accountId, podId };\n }\n\n private async createPodFiles(podName: string, initialResources?: Record<string, string>): Promise<void> {\n const podPath = path.join(this.rootDir, podName);\n await fs.mkdir(path.join(podPath, 'profile'), { recursive: true });\n\n if (!initialResources) {\n return;\n }\n\n for (const [filename, content] of Object.entries(initialResources)) {\n const normalized = path.normalize(filename);\n if (normalized.startsWith('..') || path.isAbsolute(normalized)) {\n throw new Error(`Invalid initial resource path: ${filename}`);\n }\n const filePath = path.join(podPath, normalized);\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, 'utf8');\n }\n }\n\n private writeQuints(quads: Quad[]): void {\n const db = this.sqliteRuntime.openDatabase(this.sparqlDbPath);\n try {\n createQuintsTable(db);\n const rows = quads.map((entry) => {\n const row = quadToRow(entry);\n return [row.graph, row.subject, row.predicate, row.object, row.vector] as const;\n });\n const insert = db.prepare(`\n INSERT OR IGNORE INTO quints (graph, subject, predicate, object, vector)\n VALUES (?, ?, ?, ?, ?)\n `);\n\n db.transaction(() => {\n for (const row of rows) {\n insert.run(...row);\n }\n })();\n } finally {\n db.close();\n }\n }\n\n private writeRdfIndex(quads: Quad[]): void {\n if (!this.rdfIndexPath) {\n return;\n }\n\n const index = new RdfQuadIndex({ path: this.rdfIndexPath });\n try {\n index.open();\n index.multiPut(quads);\n } finally {\n index.close();\n }\n }\n\n private buildPodQuads({ podUrl, webId, oidcIssuer }: { podUrl: string; webId: string; oidcIssuer: string }): Quad[] {\n const now = new Date().toISOString();\n const root = this.baseUrl;\n const profileUrl = iri(podUrl, 'profile/');\n const cardUrl = iri(podUrl, 'profile/card');\n const authorizationResources = buildPodAuthorizationResources({\n authMode: this.authMode,\n podUrl,\n cardUrl,\n webId,\n stableId: stableUuid,\n iri,\n });\n const rootGraph = namedNode(root);\n const podGraph = namedNode(podUrl);\n const profileGraph = namedNode(profileUrl);\n const cardGraph = namedNode(cardUrl);\n const out: Quad[] = [];\n\n const add = (graph: string, subject: string, predicate: string, object: string): void => {\n out.push(quad(namedNode(subject), namedNode(predicate), namedNode(object), namedNode(graph)));\n };\n const addLiteral = (graph: string, subject: string, predicate: string, value: string): void => {\n out.push(quad(namedNode(subject), namedNode(predicate), literal(value), namedNode(graph)));\n };\n const addDate = (graph: string, subject: string): void => {\n out.push(quad(namedNode(subject), namedNode(`${DCT}modified`), literal(now, namedNode('http://www.w3.org/2001/XMLSchema#dateTime')), namedNode(graph)));\n };\n const addContainerMeta = (resource: string, storage = false): void => {\n const graph = meta(resource);\n addDate(graph, resource);\n add(graph, resource, `${RDF}type`, `${LDP}Resource`);\n add(graph, resource, `${RDF}type`, `${LDP}Container`);\n add(graph, resource, `${RDF}type`, `${LDP}BasicContainer`);\n if (storage) {\n add(graph, resource, `${RDF}type`, `${PIM}Storage`);\n }\n addLiteral(graph, resource, `${MA}format`, 'internal/quads');\n };\n const addDocumentMeta = (resource: string): void => {\n const graph = meta(resource);\n addDate(graph, resource);\n add(graph, resource, `${RDF}type`, `${LDP}Resource`);\n };\n\n out.push(quad(namedNode(root), namedNode(`${LDP}contains`), namedNode(podUrl), rootGraph));\n out.push(quad(namedNode(podUrl), namedNode(`${LDP}contains`), namedNode(authorizationResources.rootResourceUrl), podGraph));\n out.push(quad(namedNode(podUrl), namedNode(`${LDP}contains`), namedNode(profileUrl), podGraph));\n out.push(quad(namedNode(profileUrl), namedNode(`${LDP}contains`), namedNode(authorizationResources.profileResourceUrl), profileGraph));\n out.push(quad(namedNode(profileUrl), namedNode(`${LDP}contains`), namedNode(cardUrl), profileGraph));\n out.push(quad(namedNode(profileUrl), namedNode(`${LDP}contains`), namedNode(authorizationResources.cardResourceUrl), profileGraph));\n\n addContainerMeta(root);\n addContainerMeta(podUrl, true);\n addContainerMeta(profileUrl);\n addDocumentMeta(authorizationResources.rootResourceUrl);\n addDocumentMeta(authorizationResources.profileResourceUrl);\n addDocumentMeta(cardUrl);\n addDocumentMeta(authorizationResources.cardResourceUrl);\n\n out.push(quad(namedNode(cardUrl), namedNode(`${RDF}type`), namedNode(`${FOAF}PersonalProfileDocument`), cardGraph));\n out.push(quad(namedNode(cardUrl), namedNode(`${FOAF}maker`), namedNode(webId), cardGraph));\n out.push(quad(namedNode(cardUrl), namedNode(`${FOAF}primaryTopic`), namedNode(webId), cardGraph));\n out.push(quad(namedNode(webId), namedNode(`${RDF}type`), namedNode(`${FOAF}Person`), cardGraph));\n out.push(quad(namedNode(webId), namedNode(`${SOLID}oidcIssuer`), namedNode(oidcIssuer), cardGraph));\n\n out.push(...authorizationResources.quads);\n\n return out;\n }\n\n private writeIdentityIndexes(input: {\n accountId: string;\n podId: string;\n ownerId: string;\n webIdLinkId: string;\n podUrl: string;\n webId: string;\n }): void {\n const db = this.sqliteRuntime.openDatabase(this.identityDbPath);\n try {\n createInternalKvTable(db);\n const account = {\n linkedLoginsCount: 1,\n id: input.accountId,\n '**pod**': {\n [input.podId]: {\n baseUrl: input.podUrl,\n accountId: input.accountId,\n id: input.podId,\n '**owner**': {\n [input.ownerId]: {\n podId: input.podId,\n webId: input.webId,\n visible: false,\n id: input.ownerId,\n },\n },\n },\n },\n '**webIdLink**': {\n [input.webIdLinkId]: {\n webId: input.webId,\n accountId: input.accountId,\n id: input.webIdLinkId,\n },\n },\n };\n\n const rows: Array<[string, string]> = [\n [`accounts/data/${input.accountId}`, JSON.stringify(account)],\n [`accounts/index/pod/${input.podId}`, JSON.stringify([input.accountId])],\n [`accounts/index/pod/baseUrl/${encodeURIComponent(input.podUrl)}`, JSON.stringify([input.accountId])],\n [`accounts/index/owner/${input.ownerId}`, JSON.stringify([input.accountId])],\n [`accounts/index/webIdLink/${input.webIdLinkId}`, JSON.stringify([input.accountId])],\n [`accounts/index/webIdLink/webId/${encodeURIComponent(input.webId)}`, JSON.stringify([input.accountId])],\n ];\n const insert = db.prepare(`\n INSERT INTO internal_kv (key, value, updated_at)\n VALUES (?, ?, datetime('now'))\n ON CONFLICT (key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')\n `);\n\n db.transaction(() => {\n for (const row of rows) {\n insert.run(...row);\n }\n })();\n } finally {\n db.close();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"LocalPodProvisioningService.js","sourceRoot":"","sources":["../../src/provision/LocalPodProvisioningService.ts"],"names":[],"mappings":";;;;;;AAAA,6CAAyC;AACzC,qCAAyC;AACzC,0DAA6B;AAC7B,2BAAiC;AAEjC,iEAAqD;AACrD,kEAA2D;AAC3D,4DAAiF;AAEjF,0FAA4F;AAC5F,8DAA2D;AAE3D,MAAM,GAAG,GAAG,6CAA6C,CAAC;AAC1D,MAAM,GAAG,GAAG,2BAA2B,CAAC;AACxC,MAAM,GAAG,GAAG,2BAA2B,CAAC;AACxC,MAAM,EAAE,GAAG,8BAA8B,CAAC;AAC1C,MAAM,GAAG,GAAG,iCAAiC,CAAC;AAC9C,MAAM,IAAI,GAAG,4BAA4B,CAAC;AAC1C,MAAM,KAAK,GAAG,mCAAmC,CAAC;AAElD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,gBAAW,CAAC;AAwBjD,SAAS,mBAAmB,CAAC,GAAW;IACtC,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;AAC7C,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa,EAAE,KAAa;IACrD,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qDAAqD,KAAK,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,GAAG,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1E,OAAO;QACL,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAChB,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QACvB,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;QAC/G,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;KAClB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAC,UAA8B,EAAE,OAAe;IAC3E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC/G,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAkB;IAC3C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;GAgBP,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,EAAkB;IAC/C,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED,SAAS,IAAI,CAAC,QAAgB;IAC5B,OAAO,QAAQ,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,GAAG,CAAC,IAAY,EAAE,QAAgB;IACzC,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC5C,CAAC;AAED,MAAa,2BAA2B;IAWtC,YAAmB,OAA2C;QAV7C,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;QAQ5B,kBAAa,GAAG,IAAA,gCAAgB,GAAE,CAAC;QAGlD,IAAI,CAAC,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;QAChF,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QAChF,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnC,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,KAAgC;QACrD,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,GAAG,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9G,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,MAAM,iBAAiB,CAAC;QAChH,yEAAyE;QACzE,yCAAyC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,UAAU,CAAC,aAAa,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC;QAElE,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAErF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,MAAM,QAAQ,KAAK,EAAE,CAAC,CAAC;QACjE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,OAAe,EAAE,gBAAyC;QACrF,MAAM,OAAO,GAAG,mBAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,kBAAE,CAAC,KAAK,CAAC,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACnE,MAAM,UAAU,GAAG,mBAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,mBAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/D,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAChD,MAAM,kBAAE,CAAC,KAAK,CAAC,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,IAAI,CAAC;YACH,iBAAiB,CAAC,EAAE,CAAC,CAAC;YACtB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC/B,MAAM,GAAG,GAAG,IAAA,yBAAS,EAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAU,CAAC;YAClF,CAAC,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;OAGzB,CAAC,CAAC;YAEH,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,KAAa;QACjC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,2BAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAyD;QACxG,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC5C,MAAM,sBAAsB,GAAG,IAAA,0DAA8B,EAAC;YAC5D,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM;YACN,OAAO;YACP,KAAK;YACL,QAAQ,EAAE,UAAU;YACpB,GAAG;SACJ,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,YAAY,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,GAAG,GAAW,EAAE,CAAC;QAEvB,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,OAAe,EAAE,SAAiB,EAAE,MAAc,EAAQ,EAAE;YACtF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChG,CAAC,CAAC;QACF,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,OAAe,EAAE,SAAiB,EAAE,KAAa,EAAQ,EAAE;YAC5F,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7F,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,OAAe,EAAQ,EAAE;YACvD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,2CAA2C,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1J,CAAC,CAAC;QACF,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,OAAO,GAAG,KAAK,EAAQ,EAAE;YACnE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACzB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;YACrD,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,GAAG,WAAW,CAAC,CAAC;YACtD,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,GAAG,gBAAgB,CAAC,CAAC;YAC3D,IAAI,OAAO,EAAE,CAAC;gBACZ,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,GAAG,SAAS,CAAC,CAAC;YACtD,CAAC;YACD,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC/D,CAAC,CAAC;QACF,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAQ,EAAE;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACzB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;QACvD,CAAC,CAAC;QAEF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC3F,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,SAAS,CAAC,sBAAsB,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5H,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,SAAS,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACvI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACrG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,SAAS,CAAC,sBAAsB,CAAC,eAAe,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QAEpI,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7B,eAAe,CAAC,sBAAsB,CAAC,eAAe,CAAC,CAAC;QACxD,eAAe,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;QAC3D,eAAe,CAAC,OAAO,CAAC,CAAC;QACzB,eAAe,CAAC,sBAAsB,CAAC,eAAe,CAAC,CAAC;QAExD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,yBAAyB,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACpH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC3F,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,cAAc,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAClG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACjG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,YAAY,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACpG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,SAAS,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAE7F,GAAG,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAE1C,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,oBAAoB,CAAC,KAO5B;QACC,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChE,IAAI,CAAC;YACH,qBAAqB,CAAC,EAAE,CAAC,CAAC;YAC1B,MAAM,OAAO,GAAG;gBACd,iBAAiB,EAAE,CAAC;gBACpB,EAAE,EAAE,KAAK,CAAC,SAAS;gBACnB,SAAS,EAAE;oBACT,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;wBACb,OAAO,EAAE,KAAK,CAAC,MAAM;wBACrB,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,EAAE,EAAE,KAAK,CAAC,KAAK;wBACf,WAAW,EAAE;4BACX,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;gCACf,KAAK,EAAE,KAAK,CAAC,KAAK;gCAClB,KAAK,EAAE,KAAK,CAAC,KAAK;gCAClB,OAAO,EAAE,KAAK;gCACd,EAAE,EAAE,KAAK,CAAC,OAAO;6BAClB;yBACF;qBACF;iBACF;gBACD,eAAe,EAAE;oBACf,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;wBACnB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,EAAE,EAAE,KAAK,CAAC,WAAW;qBACtB;iBACF;aACF,CAAC;YAEF,MAAM,IAAI,GAA4B;gBACpC,CAAC,iBAAiB,KAAK,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAC7D,CAAC,sBAAsB,KAAK,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gBACxE,CAAC,8BAA8B,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gBACrG,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC5E,CAAC,4BAA4B,KAAK,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;gBACpF,CAAC,kCAAkC,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;aACzG,CAAC;YACF,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;;OAIzB,CAAC,CAAC;YAEH,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC;CACF;AAvOD,kEAuOC","sourcesContent":["import { createHash } from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { DataFactory } from 'n3';\nimport type { Quad } from '@rdfjs/types';\nimport { getLoggerFor } from 'global-logger-factory';\nimport { quadToRow } from '../storage/quint/serialization';\nimport { getSqliteRuntime, type SqliteDatabase } from '../storage/SqliteRuntime';\nimport type { AuthMode } from '../authorization/AuthMode';\nimport { buildPodAuthorizationResources } from '../authorization/PodAuthorizationResources';\nimport { RdfQuadIndex } from '../storage/rdf/RdfQuadIndex';\n\nconst RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';\nconst LDP = 'http://www.w3.org/ns/ldp#';\nconst DCT = 'http://purl.org/dc/terms/';\nconst MA = 'http://www.w3.org/ns/ma-ont#';\nconst PIM = 'http://www.w3.org/ns/pim/space#';\nconst FOAF = 'http://xmlns.com/foaf/0.1/';\nconst SOLID = 'http://www.w3.org/ns/solid/terms#';\n\nconst { literal, namedNode, quad } = DataFactory;\n\nexport interface LocalPodProvisioningInput {\n podName: string;\n webId?: string;\n initialResources?: Record<string, string>;\n}\n\nexport interface LocalPodProvisioningResult {\n podUrl: string;\n accountId: string;\n podId: string;\n}\n\nexport interface LocalPodProvisioningServiceOptions {\n baseUrl: string;\n rootDir: string;\n sparqlEndpoint: string;\n identityDbUrl: string;\n rdfIndexPath?: string;\n oidcIssuer?: string;\n authMode?: AuthMode | string;\n}\n\nfunction ensureTrailingSlash(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nfunction stripSqlitePrefix(value: string, label: string): string {\n if (value.startsWith('sqlite:')) {\n return value.slice('sqlite:'.length);\n }\n if (value === ':memory:') {\n return value;\n }\n if (/^[a-z][a-z0-9+.-]*:/iu.test(value)) {\n throw new Error(`${label} must be a sqlite URL for local Pod provisioning: ${value}`);\n }\n return value;\n}\n\nfunction stableUuid(input: string): string {\n const hex = createHash('sha256').update(input).digest('hex').slice(0, 32);\n return [\n hex.slice(0, 8),\n hex.slice(8, 12),\n `4${hex.slice(13, 16)}`,\n `${((Number.parseInt(hex.slice(16, 18), 16) & 0x3f) | 0x80).toString(16).padStart(2, '0')}${hex.slice(18, 20)}`,\n hex.slice(20, 32),\n ].join('-');\n}\n\nfunction buildWebIdFromIssuer(oidcIssuer: string | undefined, podName: string): string | undefined {\n if (!oidcIssuer) {\n return undefined;\n }\n return new URL(`${encodeURIComponent(podName)}/profile/card#me`, ensureTrailingSlash(oidcIssuer)).toString();\n}\n\nfunction createQuintsTable(db: SqliteDatabase): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS quints (\n graph TEXT NOT NULL,\n subject TEXT NOT NULL,\n predicate TEXT NOT NULL,\n object TEXT NOT NULL,\n vector TEXT,\n PRIMARY KEY (graph, subject, predicate, object)\n );\n\n CREATE INDEX IF NOT EXISTS idx_spog ON quints (subject, predicate, object, graph);\n CREATE INDEX IF NOT EXISTS idx_ogsp ON quints (object, graph, subject, predicate);\n CREATE INDEX IF NOT EXISTS idx_gspo ON quints (graph, subject, predicate, object);\n CREATE INDEX IF NOT EXISTS idx_sopg ON quints (subject, object, predicate, graph);\n CREATE INDEX IF NOT EXISTS idx_pogs ON quints (predicate, object, graph, subject);\n CREATE INDEX IF NOT EXISTS idx_gpos ON quints (graph, predicate, object, subject);\n `);\n}\n\nfunction createInternalKvTable(db: SqliteDatabase): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS internal_kv (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n `);\n}\n\nfunction meta(resource: string): string {\n return `meta:${resource}`;\n}\n\nfunction iri(base: string, relative: string): string {\n return new URL(relative, base).toString();\n}\n\nexport class LocalPodProvisioningService {\n private readonly logger = getLoggerFor(this);\n private readonly baseUrl: string;\n private readonly rootDir: string;\n private readonly sparqlDbPath: string;\n private readonly identityDbPath: string;\n private readonly rdfIndexPath?: string;\n private readonly oidcIssuer?: string;\n private readonly authMode?: AuthMode | string;\n private readonly sqliteRuntime = getSqliteRuntime();\n\n public constructor(options: LocalPodProvisioningServiceOptions) {\n this.baseUrl = ensureTrailingSlash(options.baseUrl);\n this.rootDir = options.rootDir;\n this.sparqlDbPath = stripSqlitePrefix(options.sparqlEndpoint, 'sparqlEndpoint');\n this.identityDbPath = stripSqlitePrefix(options.identityDbUrl, 'identityDbUrl');\n this.rdfIndexPath = options.rdfIndexPath;\n this.oidcIssuer = options.oidcIssuer ? ensureTrailingSlash(options.oidcIssuer) : undefined;\n this.authMode = options.authMode;\n }\n\n public async createPod(input: LocalPodProvisioningInput): Promise<LocalPodProvisioningResult> {\n const podUrl = ensureTrailingSlash(new URL(`${encodeURIComponent(input.podName)}/`, this.baseUrl).toString());\n const webId = input.webId ?? buildWebIdFromIssuer(this.oidcIssuer, input.podName) ?? `${podUrl}profile/card#me`;\n // Local storage resources are protected by the Local SP issuer even when\n // their owner WebID is a Cloud identity.\n const oidcIssuer = this.baseUrl;\n const accountId = stableUuid(`account:${podUrl}:${webId}`);\n const podId = stableUuid(`pod:${podUrl}:${webId}`);\n const ownerId = stableUuid(`owner:${podId}:${webId}`);\n const webIdLinkId = stableUuid(`webIdLink:${accountId}:${webId}`);\n\n await this.createPodFiles(input.podName, input.initialResources);\n const quads = this.buildPodQuads({ podUrl, webId, oidcIssuer });\n this.writeQuints(quads);\n this.writeRdfIndex(quads);\n this.writeIdentityIndexes({ accountId, podId, ownerId, webIdLinkId, podUrl, webId });\n\n this.logger.info(`Provisioned local pod ${podUrl} for ${webId}`);\n return { podUrl, accountId, podId };\n }\n\n private async createPodFiles(podName: string, initialResources?: Record<string, string>): Promise<void> {\n const podPath = path.join(this.rootDir, podName);\n await fs.mkdir(path.join(podPath, 'profile'), { recursive: true });\n\n if (!initialResources) {\n return;\n }\n\n for (const [filename, content] of Object.entries(initialResources)) {\n const normalized = path.normalize(filename);\n if (normalized.startsWith('..') || path.isAbsolute(normalized)) {\n throw new Error(`Invalid initial resource path: ${filename}`);\n }\n const filePath = path.join(podPath, normalized);\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, 'utf8');\n }\n }\n\n private writeQuints(quads: Quad[]): void {\n const db = this.sqliteRuntime.openDatabase(this.sparqlDbPath);\n try {\n createQuintsTable(db);\n const rows = quads.map((entry) => {\n const row = quadToRow(entry);\n return [row.graph, row.subject, row.predicate, row.object, row.vector] as const;\n });\n const insert = db.prepare(`\n INSERT OR IGNORE INTO quints (graph, subject, predicate, object, vector)\n VALUES (?, ?, ?, ?, ?)\n `);\n\n db.transaction(() => {\n for (const row of rows) {\n insert.run(...row);\n }\n })();\n } finally {\n db.close();\n }\n }\n\n private writeRdfIndex(quads: Quad[]): void {\n if (!this.rdfIndexPath) {\n return;\n }\n\n const index = new RdfQuadIndex({ path: this.rdfIndexPath });\n try {\n index.open();\n index.multiPut(quads);\n } finally {\n index.close();\n }\n }\n\n private buildPodQuads({ podUrl, webId, oidcIssuer }: { podUrl: string; webId: string; oidcIssuer: string }): Quad[] {\n const now = new Date().toISOString();\n const root = this.baseUrl;\n const profileUrl = iri(podUrl, 'profile/');\n const cardUrl = iri(podUrl, 'profile/card');\n const authorizationResources = buildPodAuthorizationResources({\n authMode: this.authMode,\n podUrl,\n cardUrl,\n webId,\n stableId: stableUuid,\n iri,\n });\n const rootGraph = namedNode(root);\n const podGraph = namedNode(podUrl);\n const profileGraph = namedNode(profileUrl);\n const cardGraph = namedNode(cardUrl);\n const out: Quad[] = [];\n\n const add = (graph: string, subject: string, predicate: string, object: string): void => {\n out.push(quad(namedNode(subject), namedNode(predicate), namedNode(object), namedNode(graph)));\n };\n const addLiteral = (graph: string, subject: string, predicate: string, value: string): void => {\n out.push(quad(namedNode(subject), namedNode(predicate), literal(value), namedNode(graph)));\n };\n const addDate = (graph: string, subject: string): void => {\n out.push(quad(namedNode(subject), namedNode(`${DCT}modified`), literal(now, namedNode('http://www.w3.org/2001/XMLSchema#dateTime')), namedNode(graph)));\n };\n const addContainerMeta = (resource: string, storage = false): void => {\n const graph = meta(resource);\n addDate(graph, resource);\n add(graph, resource, `${RDF}type`, `${LDP}Resource`);\n add(graph, resource, `${RDF}type`, `${LDP}Container`);\n add(graph, resource, `${RDF}type`, `${LDP}BasicContainer`);\n if (storage) {\n add(graph, resource, `${RDF}type`, `${PIM}Storage`);\n }\n addLiteral(graph, resource, `${MA}format`, 'internal/quads');\n };\n const addDocumentMeta = (resource: string): void => {\n const graph = meta(resource);\n addDate(graph, resource);\n add(graph, resource, `${RDF}type`, `${LDP}Resource`);\n };\n\n out.push(quad(namedNode(root), namedNode(`${LDP}contains`), namedNode(podUrl), rootGraph));\n out.push(quad(namedNode(podUrl), namedNode(`${LDP}contains`), namedNode(authorizationResources.rootResourceUrl), podGraph));\n out.push(quad(namedNode(podUrl), namedNode(`${LDP}contains`), namedNode(profileUrl), podGraph));\n out.push(quad(namedNode(profileUrl), namedNode(`${LDP}contains`), namedNode(authorizationResources.profileResourceUrl), profileGraph));\n out.push(quad(namedNode(profileUrl), namedNode(`${LDP}contains`), namedNode(cardUrl), profileGraph));\n out.push(quad(namedNode(profileUrl), namedNode(`${LDP}contains`), namedNode(authorizationResources.cardResourceUrl), profileGraph));\n\n addContainerMeta(root);\n addContainerMeta(podUrl, true);\n addContainerMeta(profileUrl);\n addDocumentMeta(authorizationResources.rootResourceUrl);\n addDocumentMeta(authorizationResources.profileResourceUrl);\n addDocumentMeta(cardUrl);\n addDocumentMeta(authorizationResources.cardResourceUrl);\n\n out.push(quad(namedNode(cardUrl), namedNode(`${RDF}type`), namedNode(`${FOAF}PersonalProfileDocument`), cardGraph));\n out.push(quad(namedNode(cardUrl), namedNode(`${FOAF}maker`), namedNode(webId), cardGraph));\n out.push(quad(namedNode(cardUrl), namedNode(`${FOAF}primaryTopic`), namedNode(webId), cardGraph));\n out.push(quad(namedNode(webId), namedNode(`${RDF}type`), namedNode(`${FOAF}Person`), cardGraph));\n out.push(quad(namedNode(webId), namedNode(`${SOLID}oidcIssuer`), namedNode(oidcIssuer), cardGraph));\n out.push(quad(namedNode(webId), namedNode(`${SOLID}storage`), namedNode(podUrl), cardGraph));\n\n out.push(...authorizationResources.quads);\n\n return out;\n }\n\n private writeIdentityIndexes(input: {\n accountId: string;\n podId: string;\n ownerId: string;\n webIdLinkId: string;\n podUrl: string;\n webId: string;\n }): void {\n const db = this.sqliteRuntime.openDatabase(this.identityDbPath);\n try {\n createInternalKvTable(db);\n const account = {\n linkedLoginsCount: 1,\n id: input.accountId,\n '**pod**': {\n [input.podId]: {\n baseUrl: input.podUrl,\n accountId: input.accountId,\n id: input.podId,\n '**owner**': {\n [input.ownerId]: {\n podId: input.podId,\n webId: input.webId,\n visible: false,\n id: input.ownerId,\n },\n },\n },\n },\n '**webIdLink**': {\n [input.webIdLinkId]: {\n webId: input.webId,\n accountId: input.accountId,\n id: input.webIdLinkId,\n },\n },\n };\n\n const rows: Array<[string, string]> = [\n [`accounts/data/${input.accountId}`, JSON.stringify(account)],\n [`accounts/index/pod/${input.podId}`, JSON.stringify([input.accountId])],\n [`accounts/index/pod/baseUrl/${encodeURIComponent(input.podUrl)}`, JSON.stringify([input.accountId])],\n [`accounts/index/owner/${input.ownerId}`, JSON.stringify([input.accountId])],\n [`accounts/index/webIdLink/${input.webIdLinkId}`, JSON.stringify([input.accountId])],\n [`accounts/index/webIdLink/webId/${encodeURIComponent(input.webId)}`, JSON.stringify([input.accountId])],\n ];\n const insert = db.prepare(`\n INSERT INTO internal_kv (key, value, updated_at)\n VALUES (?, ?, datetime('now'))\n ON CONFLICT (key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')\n `);\n\n db.transaction(() => {\n for (const row of rows) {\n insert.run(...row);\n }\n })();\n } finally {\n db.close();\n }\n }\n}\n"]}
@@ -59,6 +59,9 @@ function buildStorageRoot(payload) {
59
59
  function buildPodUrl(storageRoot, podName) {
60
60
  return joinUrlPath(storageRoot, `${encodeURIComponent(podName)}/`);
61
61
  }
62
+ function buildStorageOidcIssuer(storageRoot) {
63
+ return normalizeUrlRoot(storageRoot) ?? joinUrlPath(storageRoot, '');
64
+ }
62
65
  function stripProvisionCode(settings) {
63
66
  if (!settings) {
64
67
  return undefined;
@@ -118,12 +121,13 @@ class ProvisionPodCreator extends community_server_1.BasePodCreator {
118
121
  const webId = input.webId ?? buildDefaultWebId(this.oidcIssuer ?? this.baseUrl, podName, this.relativeWebIdPath);
119
122
  const targetStorageRoot = buildStorageRoot(payload);
120
123
  const canonicalStorageUrl = buildPodUrl(targetStorageRoot, podName);
124
+ const storageOidcIssuer = buildStorageOidcIssuer(targetStorageRoot);
121
125
  if (this.targetsCurrentStorageProvider(payload, targetStorageRoot)) {
122
126
  this.provisionLogger.info(`Provision code targets current SP ${this.baseUrl}${this.currentNodeId ? ` (${this.currentNodeId})` : ''}; creating Pod directly through CSS`);
123
127
  return this.handleStandardPodCreate(input, {
124
128
  baseIdentifier: { path: canonicalStorageUrl },
125
129
  linkWebId: !input.webId,
126
- oidcIssuer: this.oidcIssuer ?? this.baseUrl,
130
+ oidcIssuer: storageOidcIssuer,
127
131
  storageUrl: canonicalStorageUrl,
128
132
  webId,
129
133
  });
@@ -161,11 +165,11 @@ class ProvisionPodCreator extends community_server_1.BasePodCreator {
161
165
  ...inputSettings,
162
166
  base: localBase,
163
167
  webId,
164
- oidcIssuer: this.baseUrl,
168
+ oidcIssuer: storageOidcIssuer,
165
169
  storage: canonicalStorageUrl,
166
170
  };
167
171
  const webIdLink = await this.prepareWebIdLink(!input.webId, webId, input.accountId, podSettings);
168
- podSettings.oidcIssuer = this.oidcIssuer ?? this.baseUrl;
172
+ podSettings.oidcIssuer = storageOidcIssuer;
169
173
  const podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink.cleanupWebIdLink);
170
174
  this.provisionLogger.info(`Provisioned pod ${podName} on SP ${payload.spUrl}, podUrl: ${podUrl}`);
171
175
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"ProvisionPodCreator.js","sourceRoot":"","sources":["../../src/provision/ProvisionPodCreator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ProvisionPodCreator\n *\n * 等位替换 CSS 的 BasePodCreator。\n *\n * 检查 settings 里有没有 provisionCode:\n * - 有 → 解码 JWT,回调远端 SP 的 /provision/pods 创建 Pod\n * - 没有 → 委托给原始 BasePodCreator(标准本地创建)\n */\n\nimport { getLoggerFor } from 'global-logger-factory';\nimport {\n BasePodCreator,\n type PodCreatorInput,\n type PodCreatorOutput,\n type BasePodCreatorArgs,\n type ResourceIdentifier,\n type PodSettings,\n ConflictHttpError,\n} from '@solid/community-server';\nimport { ProvisionCodeCodec } from './ProvisionCodeCodec';\n\nfunction joinUrlPath(baseUrl: string, relativePath: string): string {\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/u, '');\n const normalizedRelativePath = relativePath.replace(/^\\/+/u, '');\n return `${normalizedBaseUrl}/${normalizedRelativePath}`;\n}\n\nfunction normalizeOptionalUrl(url: string | undefined): string | undefined {\n const trimmed = url?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeOptionalString(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeUrlRoot(url: string | undefined): string | undefined {\n if (!url) {\n return undefined;\n }\n\n try {\n const parsed = new URL(url);\n parsed.pathname = parsed.pathname.replace(/\\/+$/u, '') || '/';\n parsed.search = '';\n parsed.hash = '';\n return parsed.toString();\n } catch {\n return undefined;\n }\n}\n\nfunction isSameUrlRoot(left: string | undefined, right: string | undefined): boolean {\n const normalizedLeft = normalizeUrlRoot(left);\n const normalizedRight = normalizeUrlRoot(right);\n return Boolean(normalizedLeft && normalizedRight && normalizedLeft === normalizedRight);\n}\n\nfunction isSameNodeId(left: string | undefined, right: string | undefined): boolean {\n return Boolean(left && right && left.trim() === right.trim());\n}\n\nfunction buildDefaultWebId(issuer: string, podName: string, relativeWebIdPath: string): string {\n const normalizedRelativePath = relativeWebIdPath.replace(/^\\/+/u, '');\n return joinUrlPath(issuer, `${encodeURIComponent(podName)}/${normalizedRelativePath}`);\n}\n\nfunction buildStorageRoot(payload: { spDomain?: string; spUrl: string }): string {\n return payload.spDomain ? `https://${payload.spDomain}` : payload.spUrl;\n}\n\nfunction buildPodUrl(storageRoot: string, podName: string): string {\n return joinUrlPath(storageRoot, `${encodeURIComponent(podName)}/`);\n}\n\nfunction stripProvisionCode(settings: PodCreatorInput['settings']): Record<string, unknown> | undefined {\n if (!settings) {\n return undefined;\n }\n\n const { provisionCode: _provisionCode, ...rest } = settings as Record<string, unknown>;\n return rest;\n}\n\nasync function readProvisionResponseMessage(response: Response): Promise<string | undefined> {\n const text = await response.text().catch(() => '');\n if (!text) {\n return undefined;\n }\n\n try {\n const body = JSON.parse(text) as { message?: unknown; error?: unknown };\n return typeof body.message === 'string'\n ? body.message\n : typeof body.error === 'string'\n ? body.error\n : text;\n } catch {\n return text;\n }\n}\n\nexport interface ProvisionPodCreatorArgs extends BasePodCreatorArgs {\n /** 与 ProvisionHandler 使用相同的 baseUrl 派生签名密钥 */\n provisionBaseUrl?: string;\n /** Current SP node id; used to recognize this SP even when URLs differ by localhost/managed domain. */\n nodeId?: string;\n /** Kept in the component signature for config compatibility; Pod storage facts live in CSS account data. */\n identityDbUrl?: string;\n}\n\ninterface StandardPodCreateOptions {\n baseIdentifier?: ResourceIdentifier;\n linkWebId?: boolean;\n oidcIssuer?: string;\n storageUrl?: string;\n webId?: string;\n}\n\ninterface PreparedWebIdLink {\n /** Link id to expose in the create-pod response. May be an existing link. */\n outputWebIdLink?: string;\n /** Link id CSS may delete if Pod creation fails. Only newly-created links are safe here. */\n cleanupWebIdLink?: string;\n}\n\nfunction remapPodConflict(error: unknown, podName: string): never {\n const message = error instanceof Error ? error.message : String(error);\n if (/There already is a resource at/i.test(message)) {\n throw new ConflictHttpError(`Pod name \"${podName}\" is already taken for this storage target.`, {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n throw error;\n}\n\nexport class ProvisionPodCreator extends BasePodCreator {\n private readonly provisionLogger = getLoggerFor(this);\n private readonly codec: ProvisionCodeCodec;\n private readonly oidcIssuer?: string;\n private readonly currentNodeId?: string;\n\n public constructor(args: ProvisionPodCreatorArgs) {\n super(args);\n this.oidcIssuer = normalizeOptionalUrl(args.provisionBaseUrl);\n this.currentNodeId = normalizeOptionalString(args.nodeId);\n this.codec = new ProvisionCodeCodec(this.oidcIssuer ?? args.baseUrl);\n }\n\n public override async handle(input: PodCreatorInput): Promise<PodCreatorOutput> {\n const provisionCode = input.settings?.provisionCode as string | undefined;\n\n if (!provisionCode) {\n return this.handleStandardPodCreate(input);\n }\n\n // SP 模式:解码 provisionCode,回调远端 SP\n const payload = this.codec.decode(provisionCode);\n if (!payload) {\n throw new Error('Invalid or expired provisionCode');\n }\n\n // 1. 确定 podName\n const podName = input.name;\n if (!podName) {\n throw new Error('Pod name is required for remote provisioning');\n }\n const webId = input.webId ?? buildDefaultWebId(this.oidcIssuer ?? this.baseUrl, podName, this.relativeWebIdPath);\n const targetStorageRoot = buildStorageRoot(payload);\n const canonicalStorageUrl = buildPodUrl(targetStorageRoot, podName);\n\n if (this.targetsCurrentStorageProvider(payload, targetStorageRoot)) {\n this.provisionLogger.info(\n `Provision code targets current SP ${this.baseUrl}${this.currentNodeId ? ` (${this.currentNodeId})` : ''}; creating Pod directly through CSS`,\n );\n return this.handleStandardPodCreate(input, {\n baseIdentifier: { path: canonicalStorageUrl },\n linkWebId: !input.webId,\n oidcIssuer: this.oidcIssuer ?? this.baseUrl,\n storageUrl: canonicalStorageUrl,\n webId,\n });\n }\n\n this.provisionLogger.info(`Provisioning pod on remote SP: ${payload.spUrl}`);\n\n // 2. 回调 SP 创建 Pod\n const callbackUrl = `${payload.spUrl.replace(/\\/$/, '')}/provision/pods`;\n const spResponse = await fetch(callbackUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${payload.serviceToken}`,\n },\n body: JSON.stringify({ podName, webId }),\n });\n\n if (!spResponse.ok) {\n const message = await readProvisionResponseMessage(spResponse);\n this.provisionLogger.error(`SP callback failed: ${spResponse.status} ${message ?? ''}`);\n if (spResponse.status === 409 || /already exists|already taken|conflict/iu.test(message ?? '')) {\n throw new ConflictHttpError(message || `Pod name \"${podName}\" is already taken for this storage target.`);\n }\n throw new Error(message\n ? `Failed to create pod on SP: ${spResponse.status}: ${message}`\n : `Failed to create pod on SP: ${spResponse.status}`);\n }\n\n const spResult = await spResponse.json() as { podUrl?: string };\n\n // storage URL 优先用 Cloud 分配的子域名,回调用实际地址\n const podUrl = spResult.podUrl || canonicalStorageUrl;\n\n // 3. 链接 WebID 到账户 + 在本地 PodStore 记录\n // base.path 必须在 Cloud 的 identifier space 内(CSS PodStore 会检查),\n // 所以用 Cloud 本地路径;真实的 SP storage URL 通过 podUrl 返回。\n const localBase = this.identifierGenerator.generate(podName);\n const inputSettings = stripProvisionCode(input.settings);\n const podSettings = {\n ...inputSettings,\n base: localBase,\n webId,\n oidcIssuer: this.baseUrl,\n storage: canonicalStorageUrl,\n };\n\n const webIdLink = await this.prepareWebIdLink(!input.webId, webId, input.accountId, podSettings);\n podSettings.oidcIssuer = this.oidcIssuer ?? this.baseUrl;\n const podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink.cleanupWebIdLink);\n\n this.provisionLogger.info(`Provisioned pod ${podName} on SP ${payload.spUrl}, podUrl: ${podUrl}`);\n\n return {\n podUrl,\n webId,\n podId,\n webIdLink: webIdLink.outputWebIdLink,\n };\n }\n\n private targetsCurrentStorageProvider(payload: { nodeId?: string; spUrl: string }, targetStorageRoot: string): boolean {\n return isSameNodeId(payload.nodeId, this.currentNodeId) ||\n isSameUrlRoot(payload.spUrl, this.baseUrl) ||\n isSameUrlRoot(targetStorageRoot, this.baseUrl);\n }\n\n private async handleStandardPodCreate(\n input: PodCreatorInput,\n options: StandardPodCreateOptions = {},\n ): Promise<PodCreatorOutput> {\n const totalStarted = Date.now();\n const baseIdentifier = options.baseIdentifier ?? this.generateBaseIdentifier(input.name);\n const inputSettings = stripProvisionCode(input.settings);\n const oidcIssuer = options.oidcIssuer ?? (typeof inputSettings?.oidcIssuer === 'string'\n ? inputSettings.oidcIssuer\n : this.oidcIssuer ?? this.baseUrl);\n const webId = options.webId ?? input.webId ?? (input.name\n ? buildDefaultWebId(oidcIssuer, input.name, this.relativeWebIdPath)\n : joinUrlPath(baseIdentifier.path, this.relativeWebIdPath));\n const storageUrl = options.storageUrl ?? baseIdentifier.path;\n const podSettings = {\n ...inputSettings,\n base: baseIdentifier,\n webId,\n oidcIssuer,\n storage: storageUrl,\n };\n const linkWebId = options.linkWebId ?? !input.webId;\n\n const webIdStarted = Date.now();\n const webIdLink = await this.prepareWebIdLink(linkWebId, webId, input.accountId, podSettings);\n podSettings.oidcIssuer = oidcIssuer;\n const webIdElapsed = Date.now() - webIdStarted;\n\n const podStarted = Date.now();\n let podId: string;\n try {\n podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink.cleanupWebIdLink);\n } catch (error) {\n if (input.name) {\n remapPodConflict(error, input.name);\n }\n throw error;\n }\n const podElapsed = Date.now() - podStarted;\n const totalElapsed = Date.now() - totalStarted;\n\n this.provisionLogger.info(\n `[timing] ProvisionPodCreator.standard account=${input.accountId} pod=${baseIdentifier.path} handleWebId=${webIdElapsed}ms createPod=${podElapsed}ms total=${totalElapsed}ms`,\n );\n\n return {\n podUrl: baseIdentifier.path,\n webId,\n podId,\n webIdLink: webIdLink.outputWebIdLink,\n };\n }\n\n private async prepareWebIdLink(\n linkWebId: boolean,\n webId: string,\n accountId: string,\n settings: PodSettings,\n ): Promise<PreparedWebIdLink> {\n if (!linkWebId) {\n return {};\n }\n\n const existingLink = await this.findExistingWebIdLink(webId, accountId);\n if (existingLink) {\n this.provisionLogger.info(`Reusing existing WebID link ${existingLink.id} for ${webId}`);\n return { outputWebIdLink: existingLink.id };\n }\n\n const createdLink = await this.handleWebId(true, webId, accountId, settings);\n return {\n outputWebIdLink: createdLink,\n cleanupWebIdLink: createdLink,\n };\n }\n\n private async findExistingWebIdLink(\n webId: string,\n accountId: string,\n ): Promise<{ id: string; webId: string } | undefined> {\n const normalizedTarget = normalizeUrlRoot(webId) ?? webId;\n const links = await this.webIdStore.findLinks(accountId);\n return links.find((link) => (normalizeUrlRoot(link.webId) ?? link.webId) === normalizedTarget);\n }\n}\n"]}
1
+ {"version":3,"file":"ProvisionPodCreator.js","sourceRoot":"","sources":["../../src/provision/ProvisionPodCreator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ProvisionPodCreator\n *\n * 等位替换 CSS 的 BasePodCreator。\n *\n * 检查 settings 里有没有 provisionCode:\n * - 有 → 解码 JWT,回调远端 SP 的 /provision/pods 创建 Pod\n * - 没有 → 委托给原始 BasePodCreator(标准本地创建)\n */\n\nimport { getLoggerFor } from 'global-logger-factory';\nimport {\n BasePodCreator,\n type PodCreatorInput,\n type PodCreatorOutput,\n type BasePodCreatorArgs,\n type ResourceIdentifier,\n type PodSettings,\n ConflictHttpError,\n} from '@solid/community-server';\nimport { ProvisionCodeCodec } from './ProvisionCodeCodec';\n\nfunction joinUrlPath(baseUrl: string, relativePath: string): string {\n const normalizedBaseUrl = baseUrl.replace(/\\/+$/u, '');\n const normalizedRelativePath = relativePath.replace(/^\\/+/u, '');\n return `${normalizedBaseUrl}/${normalizedRelativePath}`;\n}\n\nfunction normalizeOptionalUrl(url: string | undefined): string | undefined {\n const trimmed = url?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeOptionalString(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeUrlRoot(url: string | undefined): string | undefined {\n if (!url) {\n return undefined;\n }\n\n try {\n const parsed = new URL(url);\n parsed.pathname = parsed.pathname.replace(/\\/+$/u, '') || '/';\n parsed.search = '';\n parsed.hash = '';\n return parsed.toString();\n } catch {\n return undefined;\n }\n}\n\nfunction isSameUrlRoot(left: string | undefined, right: string | undefined): boolean {\n const normalizedLeft = normalizeUrlRoot(left);\n const normalizedRight = normalizeUrlRoot(right);\n return Boolean(normalizedLeft && normalizedRight && normalizedLeft === normalizedRight);\n}\n\nfunction isSameNodeId(left: string | undefined, right: string | undefined): boolean {\n return Boolean(left && right && left.trim() === right.trim());\n}\n\nfunction buildDefaultWebId(issuer: string, podName: string, relativeWebIdPath: string): string {\n const normalizedRelativePath = relativeWebIdPath.replace(/^\\/+/u, '');\n return joinUrlPath(issuer, `${encodeURIComponent(podName)}/${normalizedRelativePath}`);\n}\n\nfunction buildStorageRoot(payload: { spDomain?: string; spUrl: string }): string {\n return payload.spDomain ? `https://${payload.spDomain}` : payload.spUrl;\n}\n\nfunction buildPodUrl(storageRoot: string, podName: string): string {\n return joinUrlPath(storageRoot, `${encodeURIComponent(podName)}/`);\n}\n\nfunction buildStorageOidcIssuer(storageRoot: string): string {\n return normalizeUrlRoot(storageRoot) ?? joinUrlPath(storageRoot, '');\n}\n\nfunction stripProvisionCode(settings: PodCreatorInput['settings']): Record<string, unknown> | undefined {\n if (!settings) {\n return undefined;\n }\n\n const { provisionCode: _provisionCode, ...rest } = settings as Record<string, unknown>;\n return rest;\n}\n\nasync function readProvisionResponseMessage(response: Response): Promise<string | undefined> {\n const text = await response.text().catch(() => '');\n if (!text) {\n return undefined;\n }\n\n try {\n const body = JSON.parse(text) as { message?: unknown; error?: unknown };\n return typeof body.message === 'string'\n ? body.message\n : typeof body.error === 'string'\n ? body.error\n : text;\n } catch {\n return text;\n }\n}\n\nexport interface ProvisionPodCreatorArgs extends BasePodCreatorArgs {\n /** 与 ProvisionHandler 使用相同的 baseUrl 派生签名密钥 */\n provisionBaseUrl?: string;\n /** Current SP node id; used to recognize this SP even when URLs differ by localhost/managed domain. */\n nodeId?: string;\n /** Kept in the component signature for config compatibility; Pod storage facts live in CSS account data. */\n identityDbUrl?: string;\n}\n\ninterface StandardPodCreateOptions {\n baseIdentifier?: ResourceIdentifier;\n linkWebId?: boolean;\n oidcIssuer?: string;\n storageUrl?: string;\n webId?: string;\n}\n\ninterface PreparedWebIdLink {\n /** Link id to expose in the create-pod response. May be an existing link. */\n outputWebIdLink?: string;\n /** Link id CSS may delete if Pod creation fails. Only newly-created links are safe here. */\n cleanupWebIdLink?: string;\n}\n\nfunction remapPodConflict(error: unknown, podName: string): never {\n const message = error instanceof Error ? error.message : String(error);\n if (/There already is a resource at/i.test(message)) {\n throw new ConflictHttpError(`Pod name \"${podName}\" is already taken for this storage target.`, {\n cause: error instanceof Error ? error : undefined,\n });\n }\n\n throw error;\n}\n\nexport class ProvisionPodCreator extends BasePodCreator {\n private readonly provisionLogger = getLoggerFor(this);\n private readonly codec: ProvisionCodeCodec;\n private readonly oidcIssuer?: string;\n private readonly currentNodeId?: string;\n\n public constructor(args: ProvisionPodCreatorArgs) {\n super(args);\n this.oidcIssuer = normalizeOptionalUrl(args.provisionBaseUrl);\n this.currentNodeId = normalizeOptionalString(args.nodeId);\n this.codec = new ProvisionCodeCodec(this.oidcIssuer ?? args.baseUrl);\n }\n\n public override async handle(input: PodCreatorInput): Promise<PodCreatorOutput> {\n const provisionCode = input.settings?.provisionCode as string | undefined;\n\n if (!provisionCode) {\n return this.handleStandardPodCreate(input);\n }\n\n // SP 模式:解码 provisionCode,回调远端 SP\n const payload = this.codec.decode(provisionCode);\n if (!payload) {\n throw new Error('Invalid or expired provisionCode');\n }\n\n // 1. 确定 podName\n const podName = input.name;\n if (!podName) {\n throw new Error('Pod name is required for remote provisioning');\n }\n const webId = input.webId ?? buildDefaultWebId(this.oidcIssuer ?? this.baseUrl, podName, this.relativeWebIdPath);\n const targetStorageRoot = buildStorageRoot(payload);\n const canonicalStorageUrl = buildPodUrl(targetStorageRoot, podName);\n const storageOidcIssuer = buildStorageOidcIssuer(targetStorageRoot);\n\n if (this.targetsCurrentStorageProvider(payload, targetStorageRoot)) {\n this.provisionLogger.info(\n `Provision code targets current SP ${this.baseUrl}${this.currentNodeId ? ` (${this.currentNodeId})` : ''}; creating Pod directly through CSS`,\n );\n return this.handleStandardPodCreate(input, {\n baseIdentifier: { path: canonicalStorageUrl },\n linkWebId: !input.webId,\n oidcIssuer: storageOidcIssuer,\n storageUrl: canonicalStorageUrl,\n webId,\n });\n }\n\n this.provisionLogger.info(`Provisioning pod on remote SP: ${payload.spUrl}`);\n\n // 2. 回调 SP 创建 Pod\n const callbackUrl = `${payload.spUrl.replace(/\\/$/, '')}/provision/pods`;\n const spResponse = await fetch(callbackUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${payload.serviceToken}`,\n },\n body: JSON.stringify({ podName, webId }),\n });\n\n if (!spResponse.ok) {\n const message = await readProvisionResponseMessage(spResponse);\n this.provisionLogger.error(`SP callback failed: ${spResponse.status} ${message ?? ''}`);\n if (spResponse.status === 409 || /already exists|already taken|conflict/iu.test(message ?? '')) {\n throw new ConflictHttpError(message || `Pod name \"${podName}\" is already taken for this storage target.`);\n }\n throw new Error(message\n ? `Failed to create pod on SP: ${spResponse.status}: ${message}`\n : `Failed to create pod on SP: ${spResponse.status}`);\n }\n\n const spResult = await spResponse.json() as { podUrl?: string };\n\n // storage URL 优先用 Cloud 分配的子域名,回调用实际地址\n const podUrl = spResult.podUrl || canonicalStorageUrl;\n\n // 3. 链接 WebID 到账户 + 在本地 PodStore 记录\n // base.path 必须在 Cloud 的 identifier space 内(CSS PodStore 会检查),\n // 所以用 Cloud 本地路径;真实的 SP storage URL 通过 podUrl 返回。\n const localBase = this.identifierGenerator.generate(podName);\n const inputSettings = stripProvisionCode(input.settings);\n const podSettings = {\n ...inputSettings,\n base: localBase,\n webId,\n oidcIssuer: storageOidcIssuer,\n storage: canonicalStorageUrl,\n };\n\n const webIdLink = await this.prepareWebIdLink(!input.webId, webId, input.accountId, podSettings);\n podSettings.oidcIssuer = storageOidcIssuer;\n const podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink.cleanupWebIdLink);\n\n this.provisionLogger.info(`Provisioned pod ${podName} on SP ${payload.spUrl}, podUrl: ${podUrl}`);\n\n return {\n podUrl,\n webId,\n podId,\n webIdLink: webIdLink.outputWebIdLink,\n };\n }\n\n private targetsCurrentStorageProvider(payload: { nodeId?: string; spUrl: string }, targetStorageRoot: string): boolean {\n return isSameNodeId(payload.nodeId, this.currentNodeId) ||\n isSameUrlRoot(payload.spUrl, this.baseUrl) ||\n isSameUrlRoot(targetStorageRoot, this.baseUrl);\n }\n\n private async handleStandardPodCreate(\n input: PodCreatorInput,\n options: StandardPodCreateOptions = {},\n ): Promise<PodCreatorOutput> {\n const totalStarted = Date.now();\n const baseIdentifier = options.baseIdentifier ?? this.generateBaseIdentifier(input.name);\n const inputSettings = stripProvisionCode(input.settings);\n const oidcIssuer = options.oidcIssuer ?? (typeof inputSettings?.oidcIssuer === 'string'\n ? inputSettings.oidcIssuer\n : this.oidcIssuer ?? this.baseUrl);\n const webId = options.webId ?? input.webId ?? (input.name\n ? buildDefaultWebId(oidcIssuer, input.name, this.relativeWebIdPath)\n : joinUrlPath(baseIdentifier.path, this.relativeWebIdPath));\n const storageUrl = options.storageUrl ?? baseIdentifier.path;\n const podSettings = {\n ...inputSettings,\n base: baseIdentifier,\n webId,\n oidcIssuer,\n storage: storageUrl,\n };\n const linkWebId = options.linkWebId ?? !input.webId;\n\n const webIdStarted = Date.now();\n const webIdLink = await this.prepareWebIdLink(linkWebId, webId, input.accountId, podSettings);\n podSettings.oidcIssuer = oidcIssuer;\n const webIdElapsed = Date.now() - webIdStarted;\n\n const podStarted = Date.now();\n let podId: string;\n try {\n podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink.cleanupWebIdLink);\n } catch (error) {\n if (input.name) {\n remapPodConflict(error, input.name);\n }\n throw error;\n }\n const podElapsed = Date.now() - podStarted;\n const totalElapsed = Date.now() - totalStarted;\n\n this.provisionLogger.info(\n `[timing] ProvisionPodCreator.standard account=${input.accountId} pod=${baseIdentifier.path} handleWebId=${webIdElapsed}ms createPod=${podElapsed}ms total=${totalElapsed}ms`,\n );\n\n return {\n podUrl: baseIdentifier.path,\n webId,\n podId,\n webIdLink: webIdLink.outputWebIdLink,\n };\n }\n\n private async prepareWebIdLink(\n linkWebId: boolean,\n webId: string,\n accountId: string,\n settings: PodSettings,\n ): Promise<PreparedWebIdLink> {\n if (!linkWebId) {\n return {};\n }\n\n const existingLink = await this.findExistingWebIdLink(webId, accountId);\n if (existingLink) {\n this.provisionLogger.info(`Reusing existing WebID link ${existingLink.id} for ${webId}`);\n return { outputWebIdLink: existingLink.id };\n }\n\n const createdLink = await this.handleWebId(true, webId, accountId, settings);\n return {\n outputWebIdLink: createdLink,\n cleanupWebIdLink: createdLink,\n };\n }\n\n private async findExistingWebIdLink(\n webId: string,\n accountId: string,\n ): Promise<{ id: string; webId: string } | undefined> {\n const normalizedTarget = normalizeUrlRoot(webId) ?? webId;\n const links = await this.webIdStore.findLinks(accountId);\n return links.find((link) => (normalizeUrlRoot(link.webId) ?? link.webId) === normalizedTarget);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@undefineds.co/xpod",
3
- "version": "0.3.44",
3
+ "version": "0.3.45",
4
4
  "description": "Xpod is an extended Community Solid Server, offering rich-feature, production-level Solid Pod and identity management.",
5
5
  "repository": "https://github.com/undefinedsco/xpod",
6
6
  "author": "developer@undefineds.co",