@ubiquity-os/plugin-sdk 1.0.9 → 1.0.11
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/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -8
- package/dist/index.mjs +14 -8
- package/dist/signature.d.mts +12 -0
- package/dist/signature.d.ts +12 -0
- package/dist/signature.js +81 -0
- package/dist/signature.mjs +55 -0
- package/package.json +20 -8
package/dist/index.d.mts
CHANGED
|
@@ -36,6 +36,7 @@ interface Options$1 {
|
|
|
36
36
|
postCommentOnError?: boolean;
|
|
37
37
|
settingsSchema?: TAnySchema;
|
|
38
38
|
envSchema?: TAnySchema;
|
|
39
|
+
bypassSignatureVerification?: boolean;
|
|
39
40
|
}
|
|
40
41
|
declare function createPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
41
42
|
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ interface Options$1 {
|
|
|
36
36
|
postCommentOnError?: boolean;
|
|
37
37
|
settingsSchema?: TAnySchema;
|
|
38
38
|
envSchema?: TAnySchema;
|
|
39
|
+
bypassSignatureVerification?: boolean;
|
|
39
40
|
}
|
|
40
41
|
declare function createPlugin<TConfig = unknown, TEnv = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TSupportedEvents>) => Promise<Record<string, unknown> | undefined>, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
41
42
|
|
package/dist/index.js
CHANGED
|
@@ -164,13 +164,19 @@ var inputSchema = import_typebox.Type.Object({
|
|
|
164
164
|
authToken: import_typebox.Type.String(),
|
|
165
165
|
settings: import_typebox.Type.Record(import_typebox.Type.String(), import_typebox.Type.Any()),
|
|
166
166
|
ref: import_typebox.Type.String(),
|
|
167
|
-
signature: import_typebox.Type.String()
|
|
167
|
+
signature: import_typebox.Type.String(),
|
|
168
|
+
bypassSignatureVerification: import_typebox.Type.Optional(
|
|
169
|
+
import_typebox.Type.Boolean({
|
|
170
|
+
default: false,
|
|
171
|
+
description: "Bypass signature verification (caution: only use this if you know what you're doing)"
|
|
172
|
+
})
|
|
173
|
+
)
|
|
168
174
|
});
|
|
169
175
|
function createPlugin(handler, manifest, options) {
|
|
170
176
|
const pluginOptions = {
|
|
171
|
-
kernelPublicKey: options?.kernelPublicKey
|
|
172
|
-
logLevel: options?.logLevel
|
|
173
|
-
postCommentOnError: options?.postCommentOnError
|
|
177
|
+
kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY,
|
|
178
|
+
logLevel: options?.logLevel ?? import_ubiquity_os_logger.LOG_LEVEL.INFO,
|
|
179
|
+
postCommentOnError: options?.postCommentOnError ?? true,
|
|
174
180
|
settingsSchema: options?.settingsSchema,
|
|
175
181
|
envSchema: options?.envSchema
|
|
176
182
|
};
|
|
@@ -190,7 +196,7 @@ function createPlugin(handler, manifest, options) {
|
|
|
190
196
|
}
|
|
191
197
|
const inputs = import_value.Value.Decode(inputSchema, body);
|
|
192
198
|
const signature = inputs.signature;
|
|
193
|
-
if (!await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
|
|
199
|
+
if (!options?.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
|
|
194
200
|
throw new import_http_exception.HTTPException(400, { message: "Invalid signature" });
|
|
195
201
|
}
|
|
196
202
|
let config2;
|
|
@@ -265,11 +271,11 @@ var inputSchema2 = import_typebox2.Type.Object({
|
|
|
265
271
|
});
|
|
266
272
|
async function createActionsPlugin(handler, options) {
|
|
267
273
|
const pluginOptions = {
|
|
268
|
-
logLevel: options?.logLevel
|
|
269
|
-
postCommentOnError: options?.postCommentOnError
|
|
274
|
+
logLevel: options?.logLevel ?? import_ubiquity_os_logger2.LOG_LEVEL.INFO,
|
|
275
|
+
postCommentOnError: options?.postCommentOnError ?? true,
|
|
270
276
|
settingsSchema: options?.settingsSchema,
|
|
271
277
|
envSchema: options?.envSchema,
|
|
272
|
-
kernelPublicKey: options?.kernelPublicKey
|
|
278
|
+
kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY
|
|
273
279
|
};
|
|
274
280
|
const pluginGithubToken = process.env.PLUGIN_GITHUB_TOKEN;
|
|
275
281
|
if (!pluginGithubToken) {
|
package/dist/index.mjs
CHANGED
|
@@ -126,13 +126,19 @@ var inputSchema = T.Object({
|
|
|
126
126
|
authToken: T.String(),
|
|
127
127
|
settings: T.Record(T.String(), T.Any()),
|
|
128
128
|
ref: T.String(),
|
|
129
|
-
signature: T.String()
|
|
129
|
+
signature: T.String(),
|
|
130
|
+
bypassSignatureVerification: T.Optional(
|
|
131
|
+
T.Boolean({
|
|
132
|
+
default: false,
|
|
133
|
+
description: "Bypass signature verification (caution: only use this if you know what you're doing)"
|
|
134
|
+
})
|
|
135
|
+
)
|
|
130
136
|
});
|
|
131
137
|
function createPlugin(handler, manifest, options) {
|
|
132
138
|
const pluginOptions = {
|
|
133
|
-
kernelPublicKey: options?.kernelPublicKey
|
|
134
|
-
logLevel: options?.logLevel
|
|
135
|
-
postCommentOnError: options?.postCommentOnError
|
|
139
|
+
kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY,
|
|
140
|
+
logLevel: options?.logLevel ?? LOG_LEVEL.INFO,
|
|
141
|
+
postCommentOnError: options?.postCommentOnError ?? true,
|
|
136
142
|
settingsSchema: options?.settingsSchema,
|
|
137
143
|
envSchema: options?.envSchema
|
|
138
144
|
};
|
|
@@ -152,7 +158,7 @@ function createPlugin(handler, manifest, options) {
|
|
|
152
158
|
}
|
|
153
159
|
const inputs = Value.Decode(inputSchema, body);
|
|
154
160
|
const signature = inputs.signature;
|
|
155
|
-
if (!await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
|
|
161
|
+
if (!options?.bypassSignatureVerification && !await verifySignature(pluginOptions.kernelPublicKey, inputs, signature)) {
|
|
156
162
|
throw new HTTPException(400, { message: "Invalid signature" });
|
|
157
163
|
}
|
|
158
164
|
let config2;
|
|
@@ -227,11 +233,11 @@ var inputSchema2 = T2.Object({
|
|
|
227
233
|
});
|
|
228
234
|
async function createActionsPlugin(handler, options) {
|
|
229
235
|
const pluginOptions = {
|
|
230
|
-
logLevel: options?.logLevel
|
|
231
|
-
postCommentOnError: options?.postCommentOnError
|
|
236
|
+
logLevel: options?.logLevel ?? LOG_LEVEL2.INFO,
|
|
237
|
+
postCommentOnError: options?.postCommentOnError ?? true,
|
|
232
238
|
settingsSchema: options?.settingsSchema,
|
|
233
239
|
envSchema: options?.envSchema,
|
|
234
|
-
kernelPublicKey: options?.kernelPublicKey
|
|
240
|
+
kernelPublicKey: options?.kernelPublicKey ?? KERNEL_PUBLIC_KEY
|
|
235
241
|
};
|
|
236
242
|
const pluginGithubToken = process.env.PLUGIN_GITHUB_TOKEN;
|
|
237
243
|
if (!pluginGithubToken) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Inputs {
|
|
2
|
+
stateId: unknown;
|
|
3
|
+
eventName: unknown;
|
|
4
|
+
eventPayload: unknown;
|
|
5
|
+
authToken: unknown;
|
|
6
|
+
settings: unknown;
|
|
7
|
+
ref: unknown;
|
|
8
|
+
}
|
|
9
|
+
declare function verifySignature(publicKeyPem: string, inputs: Inputs, signature: string): Promise<boolean>;
|
|
10
|
+
declare function signPayload(payload: string, privateKey: string): Promise<string>;
|
|
11
|
+
|
|
12
|
+
export { signPayload, verifySignature };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Inputs {
|
|
2
|
+
stateId: unknown;
|
|
3
|
+
eventName: unknown;
|
|
4
|
+
eventPayload: unknown;
|
|
5
|
+
authToken: unknown;
|
|
6
|
+
settings: unknown;
|
|
7
|
+
ref: unknown;
|
|
8
|
+
}
|
|
9
|
+
declare function verifySignature(publicKeyPem: string, inputs: Inputs, signature: string): Promise<boolean>;
|
|
10
|
+
declare function signPayload(payload: string, privateKey: string): Promise<string>;
|
|
11
|
+
|
|
12
|
+
export { signPayload, verifySignature };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/signature.ts
|
|
21
|
+
var signature_exports = {};
|
|
22
|
+
__export(signature_exports, {
|
|
23
|
+
signPayload: () => signPayload,
|
|
24
|
+
verifySignature: () => verifySignature
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(signature_exports);
|
|
27
|
+
async function verifySignature(publicKeyPem, inputs, signature) {
|
|
28
|
+
try {
|
|
29
|
+
const inputsOrdered = {
|
|
30
|
+
stateId: inputs.stateId,
|
|
31
|
+
eventName: inputs.eventName,
|
|
32
|
+
eventPayload: inputs.eventPayload,
|
|
33
|
+
settings: inputs.settings,
|
|
34
|
+
authToken: inputs.authToken,
|
|
35
|
+
ref: inputs.ref
|
|
36
|
+
};
|
|
37
|
+
const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
|
|
38
|
+
const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
|
|
39
|
+
const publicKey = await crypto.subtle.importKey(
|
|
40
|
+
"spki",
|
|
41
|
+
binaryDer,
|
|
42
|
+
{
|
|
43
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
44
|
+
hash: "SHA-256"
|
|
45
|
+
},
|
|
46
|
+
true,
|
|
47
|
+
["verify"]
|
|
48
|
+
);
|
|
49
|
+
const signatureArray = Uint8Array.from(atob(signature), (c) => c.charCodeAt(0));
|
|
50
|
+
const dataArray = new TextEncoder().encode(JSON.stringify(inputsOrdered));
|
|
51
|
+
return await crypto.subtle.verify("RSASSA-PKCS1-v1_5", publicKey, signatureArray, dataArray);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error(error);
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function importRsaPrivateKey(pem) {
|
|
58
|
+
const pemContents = pem.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").trim();
|
|
59
|
+
const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
|
|
60
|
+
return await crypto.subtle.importKey(
|
|
61
|
+
"pkcs8",
|
|
62
|
+
binaryDer.buffer,
|
|
63
|
+
{
|
|
64
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
65
|
+
hash: "SHA-256"
|
|
66
|
+
},
|
|
67
|
+
true,
|
|
68
|
+
["sign"]
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
async function signPayload(payload, privateKey) {
|
|
72
|
+
const data = new TextEncoder().encode(payload);
|
|
73
|
+
const _privateKey = await importRsaPrivateKey(privateKey);
|
|
74
|
+
const signature = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", _privateKey, data);
|
|
75
|
+
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
76
|
+
}
|
|
77
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
78
|
+
0 && (module.exports = {
|
|
79
|
+
signPayload,
|
|
80
|
+
verifySignature
|
|
81
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/signature.ts
|
|
2
|
+
async function verifySignature(publicKeyPem, inputs, signature) {
|
|
3
|
+
try {
|
|
4
|
+
const inputsOrdered = {
|
|
5
|
+
stateId: inputs.stateId,
|
|
6
|
+
eventName: inputs.eventName,
|
|
7
|
+
eventPayload: inputs.eventPayload,
|
|
8
|
+
settings: inputs.settings,
|
|
9
|
+
authToken: inputs.authToken,
|
|
10
|
+
ref: inputs.ref
|
|
11
|
+
};
|
|
12
|
+
const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
|
|
13
|
+
const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
|
|
14
|
+
const publicKey = await crypto.subtle.importKey(
|
|
15
|
+
"spki",
|
|
16
|
+
binaryDer,
|
|
17
|
+
{
|
|
18
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
19
|
+
hash: "SHA-256"
|
|
20
|
+
},
|
|
21
|
+
true,
|
|
22
|
+
["verify"]
|
|
23
|
+
);
|
|
24
|
+
const signatureArray = Uint8Array.from(atob(signature), (c) => c.charCodeAt(0));
|
|
25
|
+
const dataArray = new TextEncoder().encode(JSON.stringify(inputsOrdered));
|
|
26
|
+
return await crypto.subtle.verify("RSASSA-PKCS1-v1_5", publicKey, signatureArray, dataArray);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error(error);
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function importRsaPrivateKey(pem) {
|
|
33
|
+
const pemContents = pem.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").trim();
|
|
34
|
+
const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
|
|
35
|
+
return await crypto.subtle.importKey(
|
|
36
|
+
"pkcs8",
|
|
37
|
+
binaryDer.buffer,
|
|
38
|
+
{
|
|
39
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
40
|
+
hash: "SHA-256"
|
|
41
|
+
},
|
|
42
|
+
true,
|
|
43
|
+
["sign"]
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
async function signPayload(payload, privateKey) {
|
|
47
|
+
const data = new TextEncoder().encode(payload);
|
|
48
|
+
const _privateKey = await importRsaPrivateKey(privateKey);
|
|
49
|
+
const signature = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", _privateKey, data);
|
|
50
|
+
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
signPayload,
|
|
54
|
+
verifySignature
|
|
55
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubiquity-os/plugin-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "SDK for plugin support.",
|
|
5
5
|
"author": "Ubiquity DAO",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
],
|
|
19
19
|
"constants": [
|
|
20
20
|
"dist/constants.d.ts"
|
|
21
|
+
],
|
|
22
|
+
"signature": [
|
|
23
|
+
"dist/signature.d.ts"
|
|
21
24
|
]
|
|
22
25
|
}
|
|
23
26
|
},
|
|
@@ -36,6 +39,11 @@
|
|
|
36
39
|
"types": "./dist/constants.d.ts",
|
|
37
40
|
"import": "./dist/constants.mjs",
|
|
38
41
|
"require": "./dist/constants.js"
|
|
42
|
+
},
|
|
43
|
+
"./signature": {
|
|
44
|
+
"types": "./dist/signature.d.ts",
|
|
45
|
+
"import": "./dist/signature.mjs",
|
|
46
|
+
"require": "./dist/signature.js"
|
|
39
47
|
}
|
|
40
48
|
},
|
|
41
49
|
"files": [
|
|
@@ -50,7 +58,7 @@
|
|
|
50
58
|
"knip": "knip --config .github/knip.ts",
|
|
51
59
|
"knip-ci": "knip --no-exit-code --reporter json --config .github/knip.ts",
|
|
52
60
|
"prepare": "node .husky/install.mjs",
|
|
53
|
-
"test": "jest --setupFiles dotenv/config --coverage"
|
|
61
|
+
"jest:test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --setupFiles dotenv/config --coverage"
|
|
54
62
|
},
|
|
55
63
|
"keywords": [
|
|
56
64
|
"typescript",
|
|
@@ -83,10 +91,10 @@
|
|
|
83
91
|
"@cspell/dict-software-terms": "^3.3.18",
|
|
84
92
|
"@cspell/dict-typescript": "^3.1.2",
|
|
85
93
|
"@eslint/js": "^9.14.0",
|
|
86
|
-
"@jest/globals": "29.7.0",
|
|
94
|
+
"@jest/globals": "^29.7.0",
|
|
87
95
|
"@mswjs/data": "0.16.1",
|
|
88
|
-
"@types/jest": "29.5.12",
|
|
89
96
|
"@types/node": "^20.11.19",
|
|
97
|
+
"cross-env": "^7.0.3",
|
|
90
98
|
"cspell": "^8.4.0",
|
|
91
99
|
"eslint": "^9.14.0",
|
|
92
100
|
"eslint-config-prettier": "^9.1.0",
|
|
@@ -94,13 +102,17 @@
|
|
|
94
102
|
"eslint-plugin-prettier": "^5.2.1",
|
|
95
103
|
"eslint-plugin-sonarjs": "^2.0.4",
|
|
96
104
|
"husky": "^9.0.11",
|
|
97
|
-
"jest": "29.7.0",
|
|
98
|
-
"jest-junit": "16.0.0",
|
|
99
|
-
"jest-md-dashboard": "0.8.0",
|
|
105
|
+
"jest": "^29.7.0",
|
|
106
|
+
"jest-junit": "^16.0.0",
|
|
107
|
+
"jest-md-dashboard": "^0.8.0",
|
|
100
108
|
"knip": "^5.0.1",
|
|
101
109
|
"lint-staged": "^15.2.2",
|
|
110
|
+
"msw": "^2.6.3",
|
|
111
|
+
"npm-run-all": "^4.1.5",
|
|
102
112
|
"prettier": "^3.3.3",
|
|
103
|
-
"
|
|
113
|
+
"simple-git": "^3.27.0",
|
|
114
|
+
"ts-jest": "^29.2.5",
|
|
115
|
+
"ts-node": "^10.9.2",
|
|
104
116
|
"tsup": "8.1.0",
|
|
105
117
|
"typescript": "^5.5.4",
|
|
106
118
|
"typescript-eslint": "^8.13.0"
|