@qomicex/cli 0.1.2 → 0.1.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.
- package/dist/commands/pack.js +10 -5
- package/dist/lib/signature.js +25 -1
- package/package.json +1 -1
package/dist/commands/pack.js
CHANGED
|
@@ -48,21 +48,26 @@ export async function packCommand(opts = {}) {
|
|
|
48
48
|
if (!id)
|
|
49
49
|
fail('manifest.json 缺少 id');
|
|
50
50
|
let entries = buildPackageEntries(root, manifest);
|
|
51
|
-
//
|
|
51
|
+
// 可选签名(signature.json + signature.cert.json;无商店证书时生成自签证书)
|
|
52
52
|
if (opts.key) {
|
|
53
53
|
const keyContent = await readKeyInput(opts.key);
|
|
54
54
|
const priv = parsePrivateKey(keyContent);
|
|
55
|
-
const { derivePublicKey } = await import("../lib/signature.js");
|
|
55
|
+
const { derivePublicKey, makeSelfSignedCert } = await import("../lib/signature.js");
|
|
56
56
|
const pub = await derivePublicKey(priv);
|
|
57
57
|
const keyId = `ed25519:${pub.slice(0, 8)}`;
|
|
58
58
|
const localCert = join(root, 'signature.cert.json');
|
|
59
59
|
let certJson;
|
|
60
|
-
if (existsSync(localCert))
|
|
60
|
+
if (existsSync(localCert)) {
|
|
61
61
|
certJson = readFileSync(localCert, 'utf8');
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const name = String(manifest.name ?? '');
|
|
65
|
+
certJson = await makeSelfSignedCert(priv, keyId, name);
|
|
66
|
+
writeFileSync(localCert, certJson);
|
|
67
|
+
warn('未找到本地签名证书,已生成自签证书并写入 signature.cert.json;上传商店需先在开发者中心注册对应公钥');
|
|
68
|
+
}
|
|
62
69
|
const sig = await signPackage(entries, priv, keyId, certJson);
|
|
63
70
|
entries = { ...entries, ...sig };
|
|
64
|
-
if (!certJson)
|
|
65
|
-
warn('缺少本地 signature.cert.json,商店上传仍需证书;建议改用 qomicex publish 走完整签名');
|
|
66
71
|
}
|
|
67
72
|
const outDir = resolve(root, opts.outDir ?? 'release');
|
|
68
73
|
mkdirSync(outDir, { recursive: true });
|
package/dist/lib/signature.js
CHANGED
|
@@ -98,10 +98,34 @@ async function signBytes(privDer, msg) {
|
|
|
98
98
|
const sig = await crypto.subtle.sign({ name: ALG }, key, msg);
|
|
99
99
|
return bytesToBase64(new Uint8Array(sig));
|
|
100
100
|
}
|
|
101
|
+
/** 自签开发者证书(开发者私钥签证书体):未注册商店密钥时的离线打包/本地验证用,商店上传需对应公钥已注册。 */
|
|
102
|
+
export async function makeSelfSignedCert(privDer, keyId, developerName = '') {
|
|
103
|
+
const { derivePublicKey } = await import("./signature.js");
|
|
104
|
+
const publicKey = await derivePublicKey(privDer);
|
|
105
|
+
const body = {
|
|
106
|
+
alg: ALG,
|
|
107
|
+
keyId,
|
|
108
|
+
developerId: '',
|
|
109
|
+
developerName,
|
|
110
|
+
publicKey,
|
|
111
|
+
issuedAt: new Date().toISOString(),
|
|
112
|
+
signature: '',
|
|
113
|
+
};
|
|
114
|
+
const certBody = canonicalJson({
|
|
115
|
+
alg: body.alg,
|
|
116
|
+
keyId: body.keyId,
|
|
117
|
+
developerId: body.developerId,
|
|
118
|
+
developerName: body.developerName,
|
|
119
|
+
publicKey: body.publicKey,
|
|
120
|
+
issuedAt: body.issuedAt,
|
|
121
|
+
});
|
|
122
|
+
body.signature = await signBytes(privDer, new TextEncoder().encode(certBody));
|
|
123
|
+
return JSON.stringify(body);
|
|
124
|
+
}
|
|
101
125
|
/**
|
|
102
126
|
* 对包内全部条目生成签名文件。
|
|
103
127
|
* @param certJson 商店根钥签发的开发者证书 JSON(POST /developer/keys 返回值),
|
|
104
|
-
*
|
|
128
|
+
* 省略时仅生成 signature.json(publish 场景由调用方传证书)。
|
|
105
129
|
*/
|
|
106
130
|
export async function signPackage(entries, privDer, keyId, certJson) {
|
|
107
131
|
const payload = await signedPayloadBytes(entries);
|