@undefineds.co/xpod 0.2.7 → 0.2.8
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.
|
@@ -13,6 +13,11 @@ exports.ProvisionPodCreator = void 0;
|
|
|
13
13
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
14
14
|
const community_server_1 = require("@solid/community-server");
|
|
15
15
|
const ProvisionCodeCodec_1 = require("./ProvisionCodeCodec");
|
|
16
|
+
function joinUrlPath(baseUrl, relativePath) {
|
|
17
|
+
const normalizedBaseUrl = baseUrl.replace(/\/+$/u, '');
|
|
18
|
+
const normalizedRelativePath = relativePath.replace(/^\/+/u, '');
|
|
19
|
+
return `${normalizedBaseUrl}/${normalizedRelativePath}`;
|
|
20
|
+
}
|
|
16
21
|
class ProvisionPodCreator extends community_server_1.BasePodCreator {
|
|
17
22
|
constructor(args) {
|
|
18
23
|
super(args);
|
|
@@ -81,11 +86,14 @@ class ProvisionPodCreator extends community_server_1.BasePodCreator {
|
|
|
81
86
|
async handleStandardPodCreate(input) {
|
|
82
87
|
const totalStarted = Date.now();
|
|
83
88
|
const baseIdentifier = this.generateBaseIdentifier(input.name);
|
|
84
|
-
const webId = input.webId ??
|
|
89
|
+
const webId = input.webId ?? joinUrlPath(baseIdentifier.path, this.relativeWebIdPath);
|
|
90
|
+
const inputSettings = input.settings;
|
|
91
|
+
const oidcIssuer = typeof inputSettings?.oidcIssuer === 'string' ? inputSettings.oidcIssuer : this.baseUrl;
|
|
85
92
|
const podSettings = {
|
|
86
|
-
...
|
|
93
|
+
...inputSettings,
|
|
87
94
|
base: baseIdentifier,
|
|
88
95
|
webId,
|
|
96
|
+
oidcIssuer,
|
|
89
97
|
};
|
|
90
98
|
const webIdStarted = Date.now();
|
|
91
99
|
const webIdLink = await this.handleWebId(!input.webId, webId, input.accountId, podSettings);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProvisionPodCreator.js","sourceRoot":"","sources":["../../src/provision/ProvisionPodCreator.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,iEAAqD;AACrD,8DAKiC;AACjC,6DAA0D;
|
|
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} 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\nexport interface ProvisionPodCreatorArgs extends BasePodCreatorArgs {\n /** 与 ProvisionHandler 使用相同的 baseUrl 派生签名密钥 */\n provisionBaseUrl?: string;\n}\n\nexport class ProvisionPodCreator extends BasePodCreator {\n private readonly provisionLogger = getLoggerFor(this);\n private readonly codec: ProvisionCodeCodec;\n\n public constructor(args: ProvisionPodCreatorArgs) {\n super(args);\n this.codec = new ProvisionCodeCodec(args.provisionBaseUrl ?? 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 this.provisionLogger.info(`Provisioning pod on remote SP: ${payload.spUrl}`);\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\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 }),\n });\n\n if (!spResponse.ok) {\n const errBody = await spResponse.text();\n this.provisionLogger.error(`SP callback failed: ${spResponse.status} ${errBody}`);\n throw new Error(`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 storageBase = payload.spDomain\n ? `https://${payload.spDomain}`\n : payload.spUrl.replace(/\\/$/, '');\n const podUrl = spResult.podUrl || `${storageBase}/${podName}/`;\n\n // 3. 生成 WebID(指向 Cloud,storage 指向 SP)\n const webId = input.webId ?? `${this.baseUrl}${podName}/profile/card#me`;\n\n // 4. 链接 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 podSettings = {\n ...input.settings,\n base: localBase,\n webId,\n oidcIssuer: this.baseUrl,\n };\n\n const webIdLink = await this.handleWebId(!input.webId, webId, input.accountId, podSettings);\n const podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink);\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,\n };\n }\n\n private async handleStandardPodCreate(input: PodCreatorInput): Promise<PodCreatorOutput> {\n const totalStarted = Date.now();\n const baseIdentifier = this.generateBaseIdentifier(input.name);\n const webId = input.webId ?? joinUrlPath(baseIdentifier.path, this.relativeWebIdPath);\n const inputSettings = input.settings as Record<string, unknown> | undefined;\n const oidcIssuer = typeof inputSettings?.oidcIssuer === 'string' ? inputSettings.oidcIssuer : this.baseUrl;\n const podSettings = {\n ...inputSettings,\n base: baseIdentifier,\n webId,\n oidcIssuer,\n };\n\n const webIdStarted = Date.now();\n const webIdLink = await this.handleWebId(!input.webId, webId, input.accountId, podSettings);\n const webIdElapsed = Date.now() - webIdStarted;\n\n const podStarted = Date.now();\n const podId = await this.createPod(input.accountId, podSettings, !input.name, webIdLink);\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,\n };\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undefineds.co/xpod",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
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",
|