-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
125 lines (125 loc) · 5.06 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { Buffer } from "node:buffer";
import libsodium from "https://esm.sh/libsodium-wrappers@^0.7.15";
import {
isJSONObject,
type JSONObject
} from "https://raw.githubusercontent.com/hugoalh/is-json-es/v1.0.4/mod.ts";
await libsodium.ready;
export interface GitHubRESTSetPublicKeyRequestBody {
encrypted_value: string;
key_id: string;
}
/**
* GitHub sodium sealer for encrypt value to the GitHub secret value.
*/
export class GitHubSodiumSealer {
get [Symbol.toStringTag](): string {
return "GitHubSodiumSealer";
}
#keyID?: string;
#publicKey: Buffer;
/**
* Initialize the GitHub sodium sealer.
* @param {string} publicKey Public key, which get from the GitHub organization or repository, need for encrypt value to the GitHub secret value before create or update the GitHub secret.
* @param {string} [keyID] ID of the key, which get from the GitHub organization or repository, need for create or update the GitHub secret. This parameter is optional if no need to output as part of the {@linkcode Request} body.
*/
constructor(publicKey: string, keyID?: string) {
if (!(
typeof keyID === "undefined" ||
(typeof keyID === "string" && keyID.length > 0)
)) {
throw new TypeError(`Parameter \`keyID\` is not \`undefined\`, or a string which is non empty!`);
}
if (!(publicKey.length > 0)) {
throw new SyntaxError(`Parameter \`publicKey\` is not a string which is non empty!`);
}
this.#keyID = keyID;
this.#publicKey = Buffer.from(publicKey, "base64");
}
/**
* Encrypt value to the GitHub secret value.
* @param {string} value Value that need to encrypt as the GitHub secret value.
* @returns {string} An encrypted GitHub secret value.
*/
encrypt(value: string): string {
if (!(value.length > 0)) {
throw new SyntaxError(`Parameter \`value\` is not a string which is non empty!`);
}
return Buffer.from(libsodium.crypto_box_seal(Buffer.from(value), this.#publicKey)).toString("base64");
}
/**
* Encrypt value to the GitHub secret value, and output as part of the {@linkcode Request} body for create or update GitHub secret via the GitHub REST API.
* @param {string} value Value that need to encrypt as the GitHub secret value.
* @returns {GitHubRESTSetPublicKeyRequestBody} Part of the {@linkcode Request} body for create or update GitHub secret via the GitHub REST API.
*/
encryptToRequestBody(value: string): GitHubRESTSetPublicKeyRequestBody {
if (this.#keyID !== "string") {
throw new Error(`Key ID was not defined at the initialize stage!`);
}
return {
encrypted_value: this.encrypt(value),
key_id: this.#keyID
};
}
/**
* Get the ID of the key.
* @returns {string | undefined} ID of the key.
*/
getKeyID(): string | undefined {
return this.#keyID;
}
/**
* Get the ID of the key.
* @returns {string | undefined} ID of the key.
*/
get keyID(): string | undefined {
return this.#keyID;
}
/**
* Initialize the GitHub sodium sealer with the {@linkcode Response} JSON body from get GitHub secret public key via the GitHub REST API.
* @param {JSONObject} input {@linkcode Response} JSON body.
* @returns {GitHubSodiumSealer} GitHub sodium sealer.
*/
static fromJSON(input: JSONObject): GitHubSodiumSealer {
if (
typeof input.key !== "string" ||
typeof input.key_id !== "string"
) {
throw new Error(`Parameter \`input\` is not a valid response JSON body!`);
}
return new this(input.key, input.key_id);
}
/**
* Initialize the GitHub sodium sealer with the {@linkcode Response} from get GitHub secret public key via the GitHub REST API.
* @param {Response} input {@linkcode Response}.
* @returns {Promise<GitHubSodiumSealer>} GitHub sodium sealer.
*/
static async fromResponse(input: Response): Promise<GitHubSodiumSealer> {
const responsePayload = await input.clone().json();
if (!isJSONObject(responsePayload)) {
throw new Error(`Parameter \`input\` is not a valid response!`);
}
return GitHubSodiumSealer.fromJSON(responsePayload);
}
/**
* Encrypt value to the GitHub secret value.
* @param {string} publicKey Public key, which get from the GitHub organization or repository, need for encrypt value to the GitHub secret value before create or update the GitHub secret.
* @param {string} value Value that need to encrypt as the GitHub secret value.
* @returns {string} An encrypted GitHub secret value.
* @deprecated Migrate to `new GitHubSodiumSealer(publicKey).encrypt(value)`.
*/
static seal(publicKey: string, value: string): string {
return new this(publicKey).encrypt(value);
}
}
export default GitHubSodiumSealer;
/**
* Encrypt value to the GitHub secret value.
* @param {string} publicKey Public key, which get from the GitHub organization or repository, need for encrypt value to the GitHub secret value before create or update the GitHub secret.
* @param {string} value Value that need to encrypt as the GitHub secret value.
* @returns {string} An encrypted GitHub secret value.
* @deprecated Migrate to `new GitHubSodiumSealer(publicKey).encrypt(value)`.
*/
export function seal(publicKey: string, value: string): string {
return new GitHubSodiumSealer(publicKey).encrypt(value);
}