@workos-inc/node 7.41.0 → 7.42.0
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/lib/common/exceptions/conflict.exception.d.ts +11 -0
- package/lib/common/exceptions/conflict.exception.js +21 -0
- package/lib/common/utils/test-utils.d.ts +1 -0
- package/lib/common/utils/test-utils.js +6 -1
- package/lib/vault/cryptography/decrypt.d.ts +9 -0
- package/lib/vault/cryptography/decrypt.js +37 -0
- package/lib/vault/cryptography/encrypt.d.ts +1 -0
- package/lib/vault/cryptography/encrypt.js +31 -0
- package/lib/vault/interfaces/index.d.ts +10 -0
- package/lib/vault/interfaces/index.js +26 -0
- package/lib/vault/interfaces/key/create-data-key.interface.d.ts +10 -0
- package/lib/vault/interfaces/key/create-data-key.interface.js +2 -0
- package/lib/vault/interfaces/key/decrypt-data-key.interface.d.ts +7 -0
- package/lib/vault/interfaces/key/decrypt-data-key.interface.js +2 -0
- package/lib/vault/interfaces/key.interface.d.ts +10 -0
- package/lib/vault/interfaces/key.interface.js +2 -0
- package/lib/vault/interfaces/secret/create-secret.interface.d.ts +11 -0
- package/lib/vault/interfaces/secret/create-secret.interface.js +2 -0
- package/lib/vault/interfaces/secret/delete-secret.interface.d.ts +3 -0
- package/lib/vault/interfaces/secret/delete-secret.interface.js +2 -0
- package/lib/vault/interfaces/secret/list-secret-versions.interface.d.ts +8 -0
- package/lib/vault/interfaces/secret/list-secret-versions.interface.js +2 -0
- package/lib/vault/interfaces/secret/list-secrets.interface.d.ts +5 -0
- package/lib/vault/interfaces/secret/list-secrets.interface.js +2 -0
- package/lib/vault/interfaces/secret/read-secret.interface.d.ts +19 -0
- package/lib/vault/interfaces/secret/read-secret.interface.js +2 -0
- package/lib/vault/interfaces/secret/update-secret.interface.d.ts +9 -0
- package/lib/vault/interfaces/secret/update-secret.interface.js +2 -0
- package/lib/vault/interfaces/secret.interface.d.ts +32 -0
- package/lib/vault/interfaces/secret.interface.js +2 -0
- package/lib/vault/serializers/vault-key.serializer.d.ts +5 -0
- package/lib/vault/serializers/vault-key.serializer.js +17 -0
- package/lib/vault/serializers/vault-secret.serializer.d.ts +8 -0
- package/lib/vault/serializers/vault-secret.serializer.js +55 -0
- package/lib/vault/vault-live-test.spec.d.ts +1 -0
- package/lib/vault/vault-live-test.spec.js +245 -0
- package/lib/vault/vault.d.ts +19 -0
- package/lib/vault/vault.js +97 -0
- package/lib/vault/vault.spec.d.ts +1 -0
- package/lib/vault/vault.spec.js +247 -0
- package/lib/workos.d.ts +2 -0
- package/lib/workos.js +7 -1
- package/package.json +2 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RequestException } from '../interfaces/request-exception.interface';
|
|
2
|
+
export declare class ConflictException extends Error implements RequestException {
|
|
3
|
+
readonly status = 409;
|
|
4
|
+
readonly name = "ConflictException";
|
|
5
|
+
readonly requestID: string;
|
|
6
|
+
constructor({ error, message, requestID, }: {
|
|
7
|
+
error?: string;
|
|
8
|
+
message?: string;
|
|
9
|
+
requestID: string;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConflictException = void 0;
|
|
4
|
+
class ConflictException extends Error {
|
|
5
|
+
constructor({ error, message, requestID, }) {
|
|
6
|
+
super();
|
|
7
|
+
this.status = 409;
|
|
8
|
+
this.name = 'ConflictException';
|
|
9
|
+
this.requestID = requestID;
|
|
10
|
+
if (message) {
|
|
11
|
+
this.message = message;
|
|
12
|
+
}
|
|
13
|
+
else if (error) {
|
|
14
|
+
this.message = `Error: ${error}`;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.message = `An conflict has occurred on the server.`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.ConflictException = ConflictException;
|
|
@@ -5,6 +5,7 @@ export declare function fetchSearchParams(): {
|
|
|
5
5
|
[k: string]: string;
|
|
6
6
|
};
|
|
7
7
|
export declare function fetchHeaders(): HeadersInit | undefined;
|
|
8
|
+
export declare function fetchMethod(): string | undefined;
|
|
8
9
|
export declare function fetchBody({ raw }?: {
|
|
9
10
|
raw?: boolean | undefined;
|
|
10
11
|
}): any;
|
|
@@ -14,7 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.fetchBody = exports.fetchHeaders = exports.fetchSearchParams = exports.fetchURL = exports.fetchOnce = void 0;
|
|
17
|
+
exports.fetchBody = exports.fetchMethod = exports.fetchHeaders = exports.fetchSearchParams = exports.fetchURL = exports.fetchOnce = void 0;
|
|
18
18
|
const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
|
|
19
19
|
function fetchOnce(response = {}, _a = {}) {
|
|
20
20
|
var { status = 200, headers } = _a, rest = __rest(_a, ["status", "headers"]);
|
|
@@ -34,6 +34,11 @@ function fetchHeaders() {
|
|
|
34
34
|
return (_a = jest_fetch_mock_1.default.mock.calls[0][1]) === null || _a === void 0 ? void 0 : _a.headers;
|
|
35
35
|
}
|
|
36
36
|
exports.fetchHeaders = fetchHeaders;
|
|
37
|
+
function fetchMethod() {
|
|
38
|
+
var _a;
|
|
39
|
+
return (_a = jest_fetch_mock_1.default.mock.calls[0][1]) === null || _a === void 0 ? void 0 : _a.method;
|
|
40
|
+
}
|
|
41
|
+
exports.fetchMethod = fetchMethod;
|
|
37
42
|
function fetchBody({ raw = false } = {}) {
|
|
38
43
|
var _a;
|
|
39
44
|
const body = (_a = jest_fetch_mock_1.default.mock.calls[0][1]) === null || _a === void 0 ? void 0 : _a.body;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export interface Decoded {
|
|
3
|
+
iv: Buffer;
|
|
4
|
+
tag: Buffer;
|
|
5
|
+
keys: string;
|
|
6
|
+
ciphertext: Buffer;
|
|
7
|
+
}
|
|
8
|
+
export declare const decrypt: (payload: string | Decoded, dataKey: string) => string;
|
|
9
|
+
export declare const decode: (payload: string) => Decoded;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.decode = exports.decrypt = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const leb_1 = require("leb");
|
|
9
|
+
const decrypt = (payload, dataKey) => {
|
|
10
|
+
if (typeof payload === 'string') {
|
|
11
|
+
payload = (0, exports.decode)(payload);
|
|
12
|
+
}
|
|
13
|
+
const { iv, tag, ciphertext } = payload;
|
|
14
|
+
const key = Buffer.from(dataKey, 'base64');
|
|
15
|
+
const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', key, iv);
|
|
16
|
+
decipher.setAuthTag(tag);
|
|
17
|
+
const decrypted = decipher.update(ciphertext, undefined, 'utf-8') + decipher.final('utf-8');
|
|
18
|
+
return decrypted;
|
|
19
|
+
};
|
|
20
|
+
exports.decrypt = decrypt;
|
|
21
|
+
const decode = (payload) => {
|
|
22
|
+
const inputData = Buffer.from(payload, 'base64');
|
|
23
|
+
const iv = inputData.slice(0, 32);
|
|
24
|
+
const tag = inputData.slice(32, 48);
|
|
25
|
+
const { value: keyLen, nextIndex } = (0, leb_1.decodeUInt32)(inputData, 48);
|
|
26
|
+
const keys = inputData
|
|
27
|
+
.slice(nextIndex, nextIndex + keyLen)
|
|
28
|
+
.toString('base64');
|
|
29
|
+
const ciphertext = inputData.slice(nextIndex + keyLen);
|
|
30
|
+
return {
|
|
31
|
+
iv,
|
|
32
|
+
tag,
|
|
33
|
+
keys,
|
|
34
|
+
ciphertext,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
exports.decode = decode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const encrypt: (data: string, dataKey: string, encryptedKeys: string) => string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.encrypt = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const leb_1 = require("leb");
|
|
9
|
+
const encrypt = (data, dataKey, encryptedKeys) => {
|
|
10
|
+
// encrypt using the returned data key
|
|
11
|
+
const key = Buffer.from(dataKey, 'base64');
|
|
12
|
+
const keyBlob = Buffer.from(encryptedKeys, 'base64');
|
|
13
|
+
const prefixLen = (0, leb_1.encodeUInt32)(keyBlob.length);
|
|
14
|
+
const iv = crypto_1.default.randomBytes(32);
|
|
15
|
+
const cipher = crypto_1.default.createCipheriv('aes-256-gcm', key, iv);
|
|
16
|
+
const ciphertext = Buffer.concat([
|
|
17
|
+
cipher.update(data, 'utf8'),
|
|
18
|
+
cipher.final(),
|
|
19
|
+
]);
|
|
20
|
+
const tag = cipher.getAuthTag();
|
|
21
|
+
// store the encrypted keys with the ciphertext
|
|
22
|
+
const payload = Buffer.concat([
|
|
23
|
+
iv,
|
|
24
|
+
tag,
|
|
25
|
+
prefixLen,
|
|
26
|
+
keyBlob,
|
|
27
|
+
ciphertext,
|
|
28
|
+
]).toString('base64');
|
|
29
|
+
return payload;
|
|
30
|
+
};
|
|
31
|
+
exports.encrypt = encrypt;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './key/create-data-key.interface';
|
|
2
|
+
export * from './key/decrypt-data-key.interface';
|
|
3
|
+
export * from './key.interface';
|
|
4
|
+
export * from './secret/create-secret.interface';
|
|
5
|
+
export * from './secret/delete-secret.interface';
|
|
6
|
+
export * from './secret/list-secret-versions.interface';
|
|
7
|
+
export * from './secret/list-secrets.interface';
|
|
8
|
+
export * from './secret/read-secret.interface';
|
|
9
|
+
export * from './secret/update-secret.interface';
|
|
10
|
+
export * from './secret.interface';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./key/create-data-key.interface"), exports);
|
|
18
|
+
__exportStar(require("./key/decrypt-data-key.interface"), exports);
|
|
19
|
+
__exportStar(require("./key.interface"), exports);
|
|
20
|
+
__exportStar(require("./secret/create-secret.interface"), exports);
|
|
21
|
+
__exportStar(require("./secret/delete-secret.interface"), exports);
|
|
22
|
+
__exportStar(require("./secret/list-secret-versions.interface"), exports);
|
|
23
|
+
__exportStar(require("./secret/list-secrets.interface"), exports);
|
|
24
|
+
__exportStar(require("./secret/read-secret.interface"), exports);
|
|
25
|
+
__exportStar(require("./secret/update-secret.interface"), exports);
|
|
26
|
+
__exportStar(require("./secret.interface"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SecretContext } from '../secret.interface';
|
|
2
|
+
export interface CreateSecretEntity {
|
|
3
|
+
name: string;
|
|
4
|
+
value: string;
|
|
5
|
+
key_context: SecretContext;
|
|
6
|
+
}
|
|
7
|
+
export interface CreateSecretOptions {
|
|
8
|
+
name: string;
|
|
9
|
+
value: string;
|
|
10
|
+
context: SecretContext;
|
|
11
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SecretContext, SecretUpdateBy } from '../secret.interface';
|
|
2
|
+
export interface ReadSecretOptions {
|
|
3
|
+
id: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ReadSecretMetadataResponse {
|
|
6
|
+
context: SecretContext;
|
|
7
|
+
environment_id: string;
|
|
8
|
+
id: string;
|
|
9
|
+
key_id: string;
|
|
10
|
+
updated_at: string;
|
|
11
|
+
updated_by: SecretUpdateBy;
|
|
12
|
+
version_id: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ReadSecretResponse {
|
|
15
|
+
id: string;
|
|
16
|
+
metadata: ReadSecretMetadataResponse;
|
|
17
|
+
name: string;
|
|
18
|
+
value: string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface SecretContext {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
}
|
|
4
|
+
export interface SecretDigest {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
updatedAt: Date;
|
|
8
|
+
}
|
|
9
|
+
export interface SecretUpdateBy {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SecretMetadata {
|
|
14
|
+
context: SecretContext;
|
|
15
|
+
environmentId: string;
|
|
16
|
+
id: string;
|
|
17
|
+
keyId: string;
|
|
18
|
+
updatedAt: Date;
|
|
19
|
+
updatedBy: SecretUpdateBy;
|
|
20
|
+
versionId: string;
|
|
21
|
+
}
|
|
22
|
+
export interface VaultSecret {
|
|
23
|
+
id: string;
|
|
24
|
+
metadata: SecretMetadata;
|
|
25
|
+
name: string;
|
|
26
|
+
value?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface SecretVersion {
|
|
29
|
+
createdAt: Date;
|
|
30
|
+
currentVersion: boolean;
|
|
31
|
+
id: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CreateDataKeyResponse } from '../interfaces/key/create-data-key.interface';
|
|
2
|
+
import { DecryptDataKeyResponse } from '../interfaces/key/decrypt-data-key.interface';
|
|
3
|
+
import { DataKey, DataKeyPair } from '../interfaces/key.interface';
|
|
4
|
+
export declare const deserializeCreateDataKeyResponse: (key: CreateDataKeyResponse) => DataKeyPair;
|
|
5
|
+
export declare const deserializeDecryptDataKeyResponse: (key: DecryptDataKeyResponse) => DataKey;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deserializeDecryptDataKeyResponse = exports.deserializeCreateDataKeyResponse = void 0;
|
|
4
|
+
const deserializeCreateDataKeyResponse = (key) => ({
|
|
5
|
+
context: key.context,
|
|
6
|
+
dataKey: {
|
|
7
|
+
key: key.data_key,
|
|
8
|
+
id: key.id,
|
|
9
|
+
},
|
|
10
|
+
encryptedKeys: key.encrypted_keys,
|
|
11
|
+
});
|
|
12
|
+
exports.deserializeCreateDataKeyResponse = deserializeCreateDataKeyResponse;
|
|
13
|
+
const deserializeDecryptDataKeyResponse = (key) => ({
|
|
14
|
+
key: key.data_key,
|
|
15
|
+
id: key.id,
|
|
16
|
+
});
|
|
17
|
+
exports.deserializeDecryptDataKeyResponse = deserializeDecryptDataKeyResponse;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { List, ListResponse } from '../../common/interfaces';
|
|
2
|
+
import { ReadSecretMetadataResponse, ReadSecretResponse, UpdateSecretOptions, UpdateSecretEntity, SecretMetadata, VaultSecret, SecretVersion, CreateSecretOptions, CreateSecretEntity, SecretDigestResponse, SecretDigest, ListSecretVersionsResponse } from '../interfaces';
|
|
3
|
+
export declare const deserializeSecretMetadata: (metadata: ReadSecretMetadataResponse) => SecretMetadata;
|
|
4
|
+
export declare const deserializeSecret: (secret: ReadSecretResponse) => VaultSecret;
|
|
5
|
+
export declare const deserializeListSecrets: (list: ListResponse<SecretDigestResponse>) => List<SecretDigest>;
|
|
6
|
+
export declare const desrializeListSecretVersions: (list: ListSecretVersionsResponse) => SecretVersion[];
|
|
7
|
+
export declare const serializeCreateSecretEntity: (options: CreateSecretOptions) => CreateSecretEntity;
|
|
8
|
+
export declare const serializeUpdateSecretEntity: (options: UpdateSecretOptions) => UpdateSecretEntity;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeUpdateSecretEntity = exports.serializeCreateSecretEntity = exports.desrializeListSecretVersions = exports.deserializeListSecrets = exports.deserializeSecret = exports.deserializeSecretMetadata = void 0;
|
|
4
|
+
const deserializeSecretMetadata = (metadata) => ({
|
|
5
|
+
context: metadata.context,
|
|
6
|
+
environmentId: metadata.environment_id,
|
|
7
|
+
id: metadata.id,
|
|
8
|
+
keyId: metadata.key_id,
|
|
9
|
+
updatedAt: new Date(Date.parse(metadata.updated_at)),
|
|
10
|
+
updatedBy: metadata.updated_by,
|
|
11
|
+
versionId: metadata.version_id,
|
|
12
|
+
});
|
|
13
|
+
exports.deserializeSecretMetadata = deserializeSecretMetadata;
|
|
14
|
+
const deserializeSecret = (secret) => ({
|
|
15
|
+
id: secret.id,
|
|
16
|
+
name: secret.name,
|
|
17
|
+
value: secret.value,
|
|
18
|
+
metadata: (0, exports.deserializeSecretMetadata)(secret.metadata),
|
|
19
|
+
});
|
|
20
|
+
exports.deserializeSecret = deserializeSecret;
|
|
21
|
+
const deserializeSecretDigest = (digest) => ({
|
|
22
|
+
id: digest.id,
|
|
23
|
+
name: digest.name,
|
|
24
|
+
updatedAt: new Date(Date.parse(digest.updated_at)),
|
|
25
|
+
});
|
|
26
|
+
const deserializeListSecrets = (list) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
return ({
|
|
29
|
+
object: 'list',
|
|
30
|
+
data: list.data.map(deserializeSecretDigest),
|
|
31
|
+
listMetadata: {
|
|
32
|
+
after: (_a = list.list_metadata.after) !== null && _a !== void 0 ? _a : undefined,
|
|
33
|
+
before: (_b = list.list_metadata.before) !== null && _b !== void 0 ? _b : undefined,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
exports.deserializeListSecrets = deserializeListSecrets;
|
|
38
|
+
const desrializeListSecretVersions = (list) => list.data.map(deserializeSecretVersion);
|
|
39
|
+
exports.desrializeListSecretVersions = desrializeListSecretVersions;
|
|
40
|
+
const deserializeSecretVersion = (version) => ({
|
|
41
|
+
createdAt: new Date(Date.parse(version.created_at)),
|
|
42
|
+
currentVersion: version.current_version,
|
|
43
|
+
id: version.id,
|
|
44
|
+
});
|
|
45
|
+
const serializeCreateSecretEntity = (options) => ({
|
|
46
|
+
name: options.name,
|
|
47
|
+
value: options.value,
|
|
48
|
+
key_context: options.context,
|
|
49
|
+
});
|
|
50
|
+
exports.serializeCreateSecretEntity = serializeCreateSecretEntity;
|
|
51
|
+
const serializeUpdateSecretEntity = (options) => ({
|
|
52
|
+
value: options.value,
|
|
53
|
+
version_check: options.versionCheck,
|
|
54
|
+
});
|
|
55
|
+
exports.serializeUpdateSecretEntity = serializeUpdateSecretEntity;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const jest_fetch_mock_1 = require("jest-fetch-mock");
|
|
13
|
+
const workos_1 = require("../workos");
|
|
14
|
+
const crypto_1 = require("crypto");
|
|
15
|
+
const index_worker_1 = require("../index.worker");
|
|
16
|
+
const conflict_exception_1 = require("../common/exceptions/conflict.exception");
|
|
17
|
+
describe.skip('Vault Live Test', () => {
|
|
18
|
+
let workos;
|
|
19
|
+
const secretPrefix = (0, crypto_1.randomUUID)();
|
|
20
|
+
beforeAll(() => {
|
|
21
|
+
(0, jest_fetch_mock_1.disableFetchMocks)();
|
|
22
|
+
workos = new workos_1.WorkOS('API_KEY');
|
|
23
|
+
});
|
|
24
|
+
afterAll(() => {
|
|
25
|
+
(0, jest_fetch_mock_1.enableFetchMocks)();
|
|
26
|
+
});
|
|
27
|
+
afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
let listLimit = 0;
|
|
29
|
+
let before;
|
|
30
|
+
do {
|
|
31
|
+
const allSecrets = yield workos.vault.listSecrets({ after: before });
|
|
32
|
+
for (const secret of allSecrets.data) {
|
|
33
|
+
if (secret.name.startsWith(secretPrefix)) {
|
|
34
|
+
yield workos.vault.deleteSecret({ id: secret.id });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
before = allSecrets.listMetadata.before;
|
|
38
|
+
listLimit++;
|
|
39
|
+
} while (listLimit < 100 && before !== undefined);
|
|
40
|
+
}));
|
|
41
|
+
describe('CRUD secrets', () => {
|
|
42
|
+
it('Creates secrets', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
const secretName = `${secretPrefix}-lima`;
|
|
44
|
+
const newSecret = yield workos.vault.createSecret({
|
|
45
|
+
name: secretName,
|
|
46
|
+
value: 'Huacaya 27.7 micron',
|
|
47
|
+
context: { fiber: 'Alpalca' },
|
|
48
|
+
});
|
|
49
|
+
const expectedMetadata = {
|
|
50
|
+
id: expect.any(String),
|
|
51
|
+
context: {
|
|
52
|
+
fiber: 'Alpalca',
|
|
53
|
+
},
|
|
54
|
+
environmentId: expect.any(String),
|
|
55
|
+
keyId: expect.any(String),
|
|
56
|
+
updatedAt: expect.any(Date),
|
|
57
|
+
updatedBy: {
|
|
58
|
+
id: expect.any(String),
|
|
59
|
+
name: expect.any(String),
|
|
60
|
+
},
|
|
61
|
+
versionId: expect.any(String),
|
|
62
|
+
};
|
|
63
|
+
expect(newSecret).toStrictEqual(expectedMetadata);
|
|
64
|
+
const secretValue = yield workos.vault.readSecret({ id: newSecret.id });
|
|
65
|
+
expect(secretValue).toStrictEqual({
|
|
66
|
+
id: newSecret.id,
|
|
67
|
+
name: secretName,
|
|
68
|
+
value: 'Huacaya 27.7 micron',
|
|
69
|
+
metadata: expectedMetadata,
|
|
70
|
+
});
|
|
71
|
+
}));
|
|
72
|
+
it('Fails to create secrets with the same name', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const secretName = `${secretPrefix}-lima`;
|
|
74
|
+
yield workos.vault.createSecret({
|
|
75
|
+
name: secretName,
|
|
76
|
+
value: 'Huacaya 27.7 micron',
|
|
77
|
+
context: { fiber: 'Alpalca' },
|
|
78
|
+
});
|
|
79
|
+
yield expect(workos.vault.createSecret({
|
|
80
|
+
name: secretName,
|
|
81
|
+
value: 'Huacaya 27.7 micron',
|
|
82
|
+
context: { fiber: 'Alpalca' },
|
|
83
|
+
})).rejects.toThrow(conflict_exception_1.ConflictException);
|
|
84
|
+
}));
|
|
85
|
+
it('Updates secrets', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
const secretName = `${secretPrefix}-cusco`;
|
|
87
|
+
const newSecret = yield workos.vault.createSecret({
|
|
88
|
+
name: secretName,
|
|
89
|
+
value: 'Tapada 20-30 micron',
|
|
90
|
+
context: { fiber: 'Alpalca' },
|
|
91
|
+
});
|
|
92
|
+
const updatedSecret = yield workos.vault.updateSecret({
|
|
93
|
+
id: newSecret.id,
|
|
94
|
+
value: 'Ccara 30-40 micron',
|
|
95
|
+
});
|
|
96
|
+
const expectedMetadata = {
|
|
97
|
+
id: expect.any(String),
|
|
98
|
+
context: {
|
|
99
|
+
fiber: 'Alpalca',
|
|
100
|
+
},
|
|
101
|
+
environmentId: expect.any(String),
|
|
102
|
+
keyId: expect.any(String),
|
|
103
|
+
updatedAt: expect.any(Date),
|
|
104
|
+
updatedBy: {
|
|
105
|
+
id: expect.any(String),
|
|
106
|
+
name: expect.any(String),
|
|
107
|
+
},
|
|
108
|
+
versionId: expect.any(String),
|
|
109
|
+
};
|
|
110
|
+
expect(updatedSecret).toStrictEqual({
|
|
111
|
+
id: newSecret.id,
|
|
112
|
+
name: secretName,
|
|
113
|
+
value: undefined,
|
|
114
|
+
metadata: expectedMetadata,
|
|
115
|
+
});
|
|
116
|
+
const secretValue = yield workos.vault.readSecret({ id: newSecret.id });
|
|
117
|
+
expect(secretValue).toStrictEqual({
|
|
118
|
+
id: newSecret.id,
|
|
119
|
+
name: secretName,
|
|
120
|
+
value: 'Ccara 30-40 micron',
|
|
121
|
+
metadata: expectedMetadata,
|
|
122
|
+
});
|
|
123
|
+
}));
|
|
124
|
+
it('Fails to update secrets with wrong version check', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
+
const secretName = `${secretPrefix}-cusco`;
|
|
126
|
+
const newSecret = yield workos.vault.createSecret({
|
|
127
|
+
name: secretName,
|
|
128
|
+
value: 'Tapada 20-30 micron',
|
|
129
|
+
context: { fiber: 'Alpalca' },
|
|
130
|
+
});
|
|
131
|
+
yield workos.vault.updateSecret({
|
|
132
|
+
id: newSecret.id,
|
|
133
|
+
value: 'Ccara 30-40 micron',
|
|
134
|
+
});
|
|
135
|
+
yield expect(workos.vault.updateSecret({
|
|
136
|
+
id: newSecret.id,
|
|
137
|
+
value: 'Ccara 30-40 micron',
|
|
138
|
+
versionCheck: newSecret.versionId,
|
|
139
|
+
})).rejects.toThrow(conflict_exception_1.ConflictException);
|
|
140
|
+
}));
|
|
141
|
+
it('Deletes secrets', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
142
|
+
const secretName = `${secretPrefix}-machu`;
|
|
143
|
+
const newSecret = yield workos.vault.createSecret({
|
|
144
|
+
name: secretName,
|
|
145
|
+
value: 'Tapada 20-30 micron',
|
|
146
|
+
context: { fiber: 'Alpalca' },
|
|
147
|
+
});
|
|
148
|
+
yield workos.vault.deleteSecret({ id: newSecret.id });
|
|
149
|
+
yield expect(workos.vault.readSecret({ id: newSecret.id })).rejects.toThrow(index_worker_1.NotFoundException);
|
|
150
|
+
}));
|
|
151
|
+
it('Describes secrets', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
+
const secretName = `${(0, crypto_1.randomUUID)()}-trujillo`;
|
|
153
|
+
const newSecret = yield workos.vault.createSecret({
|
|
154
|
+
name: secretName,
|
|
155
|
+
value: 'Qiviut 11-13 micron',
|
|
156
|
+
context: { fiber: 'Musk Ox' },
|
|
157
|
+
});
|
|
158
|
+
const secretDescription = yield workos.vault.describeSecret({
|
|
159
|
+
id: newSecret.id,
|
|
160
|
+
});
|
|
161
|
+
const expectedMetadata = {
|
|
162
|
+
id: expect.any(String),
|
|
163
|
+
context: {
|
|
164
|
+
fiber: 'Musk Ox',
|
|
165
|
+
},
|
|
166
|
+
environmentId: expect.any(String),
|
|
167
|
+
keyId: expect.any(String),
|
|
168
|
+
updatedAt: expect.any(Date),
|
|
169
|
+
updatedBy: {
|
|
170
|
+
id: expect.any(String),
|
|
171
|
+
name: expect.any(String),
|
|
172
|
+
},
|
|
173
|
+
versionId: expect.any(String),
|
|
174
|
+
};
|
|
175
|
+
expect(secretDescription).toStrictEqual({
|
|
176
|
+
id: newSecret.id,
|
|
177
|
+
name: secretName,
|
|
178
|
+
metadata: expectedMetadata,
|
|
179
|
+
value: undefined,
|
|
180
|
+
});
|
|
181
|
+
}));
|
|
182
|
+
it('Lists secrets with pagination', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
183
|
+
const secretNames = [];
|
|
184
|
+
const numSecrets = 6;
|
|
185
|
+
const listPrefix = `${secretPrefix}-${(0, crypto_1.randomUUID)()}`;
|
|
186
|
+
for (let i = 0; i < numSecrets; i++) {
|
|
187
|
+
const secretName = `${listPrefix}-${i}`;
|
|
188
|
+
yield workos.vault.createSecret({
|
|
189
|
+
name: secretName,
|
|
190
|
+
value: 'Qiviut 11-13 micron',
|
|
191
|
+
context: { fiber: 'Musk Ox' },
|
|
192
|
+
});
|
|
193
|
+
secretNames.push(secretName);
|
|
194
|
+
}
|
|
195
|
+
const allSecretNames = [];
|
|
196
|
+
let before;
|
|
197
|
+
do {
|
|
198
|
+
const list = yield workos.vault.listSecrets({
|
|
199
|
+
limit: 2,
|
|
200
|
+
after: before,
|
|
201
|
+
});
|
|
202
|
+
for (const secret of list.data) {
|
|
203
|
+
if (secret.name.startsWith(listPrefix)) {
|
|
204
|
+
allSecretNames.push(secret.name);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
before = list.listMetadata.before;
|
|
208
|
+
} while (before !== undefined);
|
|
209
|
+
const missingSecrets = secretNames.filter((name) => !allSecretNames.includes(name));
|
|
210
|
+
expect(allSecretNames.length).toEqual(numSecrets);
|
|
211
|
+
expect(missingSecrets).toStrictEqual([]);
|
|
212
|
+
}));
|
|
213
|
+
it('Lists secret versions', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
const secretName = `${secretPrefix}-arequipa`;
|
|
215
|
+
const newSecret = yield workos.vault.createSecret({
|
|
216
|
+
name: secretName,
|
|
217
|
+
value: 'Tapada 20-30 micron',
|
|
218
|
+
context: { fiber: 'Alpalca' },
|
|
219
|
+
});
|
|
220
|
+
const updatedSecret = yield workos.vault.updateSecret({
|
|
221
|
+
id: newSecret.id,
|
|
222
|
+
value: 'Ccara 30-40 micron',
|
|
223
|
+
});
|
|
224
|
+
const versions = yield workos.vault.listSecretVersions({
|
|
225
|
+
id: newSecret.id,
|
|
226
|
+
});
|
|
227
|
+
expect(versions.length).toBe(2);
|
|
228
|
+
const currentVersion = versions.find((v) => v.currentVersion);
|
|
229
|
+
expect(currentVersion === null || currentVersion === void 0 ? void 0 : currentVersion.id).toBe(updatedSecret.metadata.versionId);
|
|
230
|
+
const firstVersion = versions.find((v) => v.id === newSecret.versionId);
|
|
231
|
+
expect(firstVersion === null || firstVersion === void 0 ? void 0 : firstVersion.currentVersion).toBe(false);
|
|
232
|
+
}));
|
|
233
|
+
});
|
|
234
|
+
describe('encrypt and decrypt', () => {
|
|
235
|
+
it('encrypts and decrypts data', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
236
|
+
const superSecret = 'hot water freezes faster than cold water';
|
|
237
|
+
const keyContext = {
|
|
238
|
+
everything: 'everywhere',
|
|
239
|
+
};
|
|
240
|
+
const encrypted = yield workos.vault.encrypt(superSecret, keyContext);
|
|
241
|
+
const decrypted = yield workos.vault.decrypt(encrypted);
|
|
242
|
+
expect(decrypted).toBe(superSecret);
|
|
243
|
+
}));
|
|
244
|
+
});
|
|
245
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PaginationOptions } from '../index.worker';
|
|
2
|
+
import { WorkOS } from '../workos';
|
|
3
|
+
import { CreateDataKeyOptions, CreateSecretOptions, DataKey, DataKeyPair, DecryptDataKeyOptions, DeleteSecretOptions, ReadSecretOptions, SecretContext, SecretDigest, SecretMetadata, SecretVersion, UpdateSecretOptions, VaultSecret } from './interfaces';
|
|
4
|
+
import { List } from '../common/interfaces';
|
|
5
|
+
export declare class Vault {
|
|
6
|
+
private readonly workos;
|
|
7
|
+
constructor(workos: WorkOS);
|
|
8
|
+
createSecret(options: CreateSecretOptions): Promise<SecretMetadata>;
|
|
9
|
+
listSecrets(options?: PaginationOptions | undefined): Promise<List<SecretDigest>>;
|
|
10
|
+
listSecretVersions(options: ReadSecretOptions): Promise<SecretVersion[]>;
|
|
11
|
+
readSecret(options: ReadSecretOptions): Promise<VaultSecret>;
|
|
12
|
+
describeSecret(options: ReadSecretOptions): Promise<VaultSecret>;
|
|
13
|
+
updateSecret(options: UpdateSecretOptions): Promise<VaultSecret>;
|
|
14
|
+
deleteSecret(options: DeleteSecretOptions): Promise<void>;
|
|
15
|
+
createDataKey(options: CreateDataKeyOptions): Promise<DataKeyPair>;
|
|
16
|
+
decryptDataKey(options: DecryptDataKeyOptions): Promise<DataKey>;
|
|
17
|
+
encrypt(data: string, context: SecretContext): Promise<string>;
|
|
18
|
+
decrypt(encryptedData: string): Promise<string>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Vault = void 0;
|
|
13
|
+
const decrypt_1 = require("./cryptography/decrypt");
|
|
14
|
+
const encrypt_1 = require("./cryptography/encrypt");
|
|
15
|
+
const vault_key_serializer_1 = require("./serializers/vault-key.serializer");
|
|
16
|
+
const vault_secret_serializer_1 = require("./serializers/vault-secret.serializer");
|
|
17
|
+
class Vault {
|
|
18
|
+
constructor(workos) {
|
|
19
|
+
this.workos = workos;
|
|
20
|
+
}
|
|
21
|
+
createSecret(options) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const { data } = yield this.workos.post(`/vault/v1/kv`, (0, vault_secret_serializer_1.serializeCreateSecretEntity)(options));
|
|
24
|
+
return (0, vault_secret_serializer_1.deserializeSecretMetadata)(data);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
listSecrets(options) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
const url = new URL('/vault/v1/kv', this.workos.baseURL);
|
|
30
|
+
if (options === null || options === void 0 ? void 0 : options.after) {
|
|
31
|
+
url.searchParams.set('after', options.after);
|
|
32
|
+
}
|
|
33
|
+
if (options === null || options === void 0 ? void 0 : options.limit) {
|
|
34
|
+
url.searchParams.set('limit', options.limit.toString());
|
|
35
|
+
}
|
|
36
|
+
const { data } = yield this.workos.get(url.toString());
|
|
37
|
+
return (0, vault_secret_serializer_1.deserializeListSecrets)(data);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
listSecretVersions(options) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const { data } = yield this.workos.get(`/vault/v1/kv/${encodeURIComponent(options.id)}/versions`);
|
|
43
|
+
return (0, vault_secret_serializer_1.desrializeListSecretVersions)(data);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
readSecret(options) {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const { data } = yield this.workos.get(`/vault/v1/kv/${encodeURIComponent(options.id)}`);
|
|
49
|
+
return (0, vault_secret_serializer_1.deserializeSecret)(data);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
describeSecret(options) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
const { data } = yield this.workos.get(`/vault/v1/kv/${encodeURIComponent(options.id)}/metadata`);
|
|
55
|
+
return (0, vault_secret_serializer_1.deserializeSecret)(data);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
updateSecret(options) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const { data } = yield this.workos.put(`/vault/v1/kv/${encodeURIComponent(options.id)}`, (0, vault_secret_serializer_1.serializeUpdateSecretEntity)(options));
|
|
61
|
+
return (0, vault_secret_serializer_1.deserializeSecret)(data);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
deleteSecret(options) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
return this.workos.delete(`/vault/v1/kv/${encodeURIComponent(options.id)}`);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
createDataKey(options) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
const { data } = yield this.workos.post(`/vault/v1/keys/data-key`, options);
|
|
72
|
+
return (0, vault_key_serializer_1.deserializeCreateDataKeyResponse)(data);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
decryptDataKey(options) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
const { data } = yield this.workos.post(`/vault/v1/keys/decrypt`, options);
|
|
78
|
+
return (0, vault_key_serializer_1.deserializeDecryptDataKeyResponse)(data);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
encrypt(data, context) {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
const { dataKey, encryptedKeys } = yield this.createDataKey({
|
|
84
|
+
context,
|
|
85
|
+
});
|
|
86
|
+
return (0, encrypt_1.encrypt)(data, dataKey.key, encryptedKeys);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
decrypt(encryptedData) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
const decoded = (0, decrypt_1.decode)(encryptedData);
|
|
92
|
+
const dataKey = yield this.decryptDataKey({ keys: decoded.keys });
|
|
93
|
+
return (0, decrypt_1.decrypt)(decoded, dataKey.key);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.Vault = Vault;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
|
|
16
|
+
const test_utils_1 = require("../common/utils/test-utils");
|
|
17
|
+
const workos_1 = require("../workos");
|
|
18
|
+
const conflict_exception_1 = require("../common/exceptions/conflict.exception");
|
|
19
|
+
const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
20
|
+
describe('Vault', () => {
|
|
21
|
+
beforeEach(() => jest_fetch_mock_1.default.resetMocks());
|
|
22
|
+
describe('createSecret', () => {
|
|
23
|
+
it('creates secret', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
const secretName = 'charger';
|
|
25
|
+
(0, test_utils_1.fetchOnce)({
|
|
26
|
+
id: 's1',
|
|
27
|
+
context: {
|
|
28
|
+
type: 'spore',
|
|
29
|
+
},
|
|
30
|
+
environment_id: 'xxx',
|
|
31
|
+
key_id: 'k1',
|
|
32
|
+
updated_at: '2029-03-17T04:37:46.748303Z',
|
|
33
|
+
updated_by: {
|
|
34
|
+
id: 'key_xxx',
|
|
35
|
+
name: 'Local Test Key',
|
|
36
|
+
},
|
|
37
|
+
version_id: 'v1',
|
|
38
|
+
});
|
|
39
|
+
const resource = yield workos.vault.createSecret({
|
|
40
|
+
name: secretName,
|
|
41
|
+
context: { type: 'spore' },
|
|
42
|
+
value: 'Full speed ahead',
|
|
43
|
+
});
|
|
44
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv`);
|
|
45
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('POST');
|
|
46
|
+
expect(resource).toStrictEqual({
|
|
47
|
+
id: 's1',
|
|
48
|
+
context: {
|
|
49
|
+
type: 'spore',
|
|
50
|
+
},
|
|
51
|
+
environmentId: 'xxx',
|
|
52
|
+
keyId: 'k1',
|
|
53
|
+
updatedAt: new Date(Date.parse('2029-03-17T04:37:46.748303Z')),
|
|
54
|
+
updatedBy: {
|
|
55
|
+
id: 'key_xxx',
|
|
56
|
+
name: 'Local Test Key',
|
|
57
|
+
},
|
|
58
|
+
versionId: 'v1',
|
|
59
|
+
});
|
|
60
|
+
}));
|
|
61
|
+
it('throws an error if secret exists', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
+
const secretName = 'charger';
|
|
63
|
+
(0, test_utils_1.fetchOnce)({
|
|
64
|
+
error: 'Item already exists',
|
|
65
|
+
}, { status: 409 });
|
|
66
|
+
yield expect(workos.vault.createSecret({
|
|
67
|
+
name: secretName,
|
|
68
|
+
context: { type: 'spore' },
|
|
69
|
+
value: 'Full speed ahead',
|
|
70
|
+
})).rejects.toThrow(conflict_exception_1.ConflictException);
|
|
71
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv`);
|
|
72
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('POST');
|
|
73
|
+
}));
|
|
74
|
+
});
|
|
75
|
+
describe('readSecret', () => {
|
|
76
|
+
it('reads a secret by id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
const secretName = 'lima';
|
|
78
|
+
const secretId = 'secret1';
|
|
79
|
+
(0, test_utils_1.fetchOnce)({
|
|
80
|
+
id: secretId,
|
|
81
|
+
metadata: {
|
|
82
|
+
id: secretId,
|
|
83
|
+
context: {
|
|
84
|
+
emporer: 'groove',
|
|
85
|
+
},
|
|
86
|
+
environment_id: 'environment_d',
|
|
87
|
+
key_id: 'key1',
|
|
88
|
+
updated_at: '2025-03-11T02:18:54.250931Z',
|
|
89
|
+
updated_by: {
|
|
90
|
+
id: 'key_xxx',
|
|
91
|
+
name: 'Local Test Key',
|
|
92
|
+
},
|
|
93
|
+
version_id: 'version1',
|
|
94
|
+
},
|
|
95
|
+
name: secretName,
|
|
96
|
+
value: 'Pull the lever Gronk',
|
|
97
|
+
});
|
|
98
|
+
const resource = yield workos.vault.readSecret({
|
|
99
|
+
id: secretId,
|
|
100
|
+
});
|
|
101
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv/${secretId}`);
|
|
102
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('GET');
|
|
103
|
+
expect(resource).toStrictEqual({
|
|
104
|
+
id: secretId,
|
|
105
|
+
metadata: {
|
|
106
|
+
id: secretId,
|
|
107
|
+
context: {
|
|
108
|
+
emporer: 'groove',
|
|
109
|
+
},
|
|
110
|
+
environmentId: 'environment_d',
|
|
111
|
+
keyId: 'key1',
|
|
112
|
+
updatedAt: new Date(Date.parse('2025-03-11T02:18:54.250931Z')),
|
|
113
|
+
updatedBy: {
|
|
114
|
+
id: 'key_xxx',
|
|
115
|
+
name: 'Local Test Key',
|
|
116
|
+
},
|
|
117
|
+
versionId: 'version1',
|
|
118
|
+
},
|
|
119
|
+
name: secretName,
|
|
120
|
+
value: 'Pull the lever Gronk',
|
|
121
|
+
});
|
|
122
|
+
}));
|
|
123
|
+
});
|
|
124
|
+
describe('listSecrets', () => {
|
|
125
|
+
it('gets a paginated list of secrets', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
+
(0, test_utils_1.fetchOnce)({
|
|
127
|
+
data: [
|
|
128
|
+
{
|
|
129
|
+
id: 's1',
|
|
130
|
+
name: 'charger',
|
|
131
|
+
updated_at: '2029-03-17T04:37:46.748303Z',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
list_metadata: {
|
|
135
|
+
after: null,
|
|
136
|
+
before: 'charger',
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
const resource = yield workos.vault.listSecrets();
|
|
140
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv`);
|
|
141
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('GET');
|
|
142
|
+
expect(resource).toStrictEqual({
|
|
143
|
+
object: 'list',
|
|
144
|
+
data: [
|
|
145
|
+
{
|
|
146
|
+
id: 's1',
|
|
147
|
+
name: 'charger',
|
|
148
|
+
updatedAt: new Date(Date.parse('2029-03-17T04:37:46.748303Z')),
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
listMetadata: {
|
|
152
|
+
after: undefined,
|
|
153
|
+
before: 'charger',
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}));
|
|
157
|
+
});
|
|
158
|
+
describe('listSecretVersions', () => {
|
|
159
|
+
it('gets a paginated list of secret versions', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
(0, test_utils_1.fetchOnce)({
|
|
161
|
+
data: [
|
|
162
|
+
{
|
|
163
|
+
id: 'raZUqoHteQkLihH6AG5bj6sYAqMcJS76',
|
|
164
|
+
size: 270,
|
|
165
|
+
etag: '"5147c963627323edcb15910ceea573bf"',
|
|
166
|
+
created_at: '2029-03-17T15:51:57.000000Z',
|
|
167
|
+
current_version: true,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
list_metadata: {
|
|
171
|
+
after: null,
|
|
172
|
+
before: 'raZUqoHteQkLihH6AG5bj6sYAqMcJS76',
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
const resource = yield workos.vault.listSecretVersions({ id: 'secret1' });
|
|
176
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv/secret1/versions`);
|
|
177
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('GET');
|
|
178
|
+
expect(resource).toStrictEqual([
|
|
179
|
+
{
|
|
180
|
+
createdAt: new Date(Date.parse('2029-03-17T15:51:57.000000Z')),
|
|
181
|
+
currentVersion: true,
|
|
182
|
+
id: 'raZUqoHteQkLihH6AG5bj6sYAqMcJS76',
|
|
183
|
+
},
|
|
184
|
+
]);
|
|
185
|
+
}));
|
|
186
|
+
});
|
|
187
|
+
describe('updateSecret', () => {
|
|
188
|
+
it('updates secret', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
189
|
+
const secretId = 's1';
|
|
190
|
+
(0, test_utils_1.fetchOnce)({
|
|
191
|
+
id: secretId,
|
|
192
|
+
name: 'charger',
|
|
193
|
+
metadata: {
|
|
194
|
+
id: secretId,
|
|
195
|
+
context: {
|
|
196
|
+
type: 'spore',
|
|
197
|
+
},
|
|
198
|
+
environment_id: 'xxx',
|
|
199
|
+
key_id: 'k1',
|
|
200
|
+
updated_at: '2029-03-17T04:37:46.748303Z',
|
|
201
|
+
updated_by: {
|
|
202
|
+
id: 'key_xxx',
|
|
203
|
+
name: 'Local Test Key',
|
|
204
|
+
},
|
|
205
|
+
version_id: 'v1',
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
const resource = yield workos.vault.updateSecret({
|
|
209
|
+
id: secretId,
|
|
210
|
+
value: 'Full speed ahead',
|
|
211
|
+
});
|
|
212
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv/${secretId}`);
|
|
213
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('PUT');
|
|
214
|
+
expect(resource).toStrictEqual({
|
|
215
|
+
id: secretId,
|
|
216
|
+
name: 'charger',
|
|
217
|
+
metadata: {
|
|
218
|
+
id: secretId,
|
|
219
|
+
context: {
|
|
220
|
+
type: 'spore',
|
|
221
|
+
},
|
|
222
|
+
environmentId: 'xxx',
|
|
223
|
+
keyId: 'k1',
|
|
224
|
+
updatedAt: new Date(Date.parse('2029-03-17T04:37:46.748303Z')),
|
|
225
|
+
updatedBy: {
|
|
226
|
+
id: 'key_xxx',
|
|
227
|
+
name: 'Local Test Key',
|
|
228
|
+
},
|
|
229
|
+
versionId: 'v1',
|
|
230
|
+
},
|
|
231
|
+
value: undefined,
|
|
232
|
+
});
|
|
233
|
+
}));
|
|
234
|
+
it('throws an error if secret version check fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
235
|
+
(0, test_utils_1.fetchOnce)({
|
|
236
|
+
error: 'Item already exists',
|
|
237
|
+
}, { status: 409 });
|
|
238
|
+
yield expect(workos.vault.updateSecret({
|
|
239
|
+
id: 'secret1',
|
|
240
|
+
value: 'Full speed ahead',
|
|
241
|
+
versionCheck: 'notaversion',
|
|
242
|
+
})).rejects.toThrow(conflict_exception_1.ConflictException);
|
|
243
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/vault/v1/kv/secret1`);
|
|
244
|
+
expect((0, test_utils_1.fetchMethod)()).toBe('PUT');
|
|
245
|
+
}));
|
|
246
|
+
});
|
|
247
|
+
});
|
package/lib/workos.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { HttpClient } from './common/net/http-client';
|
|
|
15
15
|
import { IronSessionProvider } from './common/iron-session/iron-session-provider';
|
|
16
16
|
import { Widgets } from './widgets/widgets';
|
|
17
17
|
import { Actions } from './actions/actions';
|
|
18
|
+
import { Vault } from './vault/vault';
|
|
18
19
|
export declare class WorkOS {
|
|
19
20
|
readonly key?: string | undefined;
|
|
20
21
|
readonly options: WorkOSOptions;
|
|
@@ -35,6 +36,7 @@ export declare class WorkOS {
|
|
|
35
36
|
readonly userManagement: UserManagement;
|
|
36
37
|
readonly fga: FGA;
|
|
37
38
|
readonly widgets: Widgets;
|
|
39
|
+
readonly vault: Vault;
|
|
38
40
|
constructor(key?: string | undefined, options?: WorkOSOptions);
|
|
39
41
|
createWebhookClient(): Webhooks;
|
|
40
42
|
createActionsClient(): Actions;
|
package/lib/workos.js
CHANGED
|
@@ -29,7 +29,9 @@ const subtle_crypto_provider_1 = require("./common/crypto/subtle-crypto-provider
|
|
|
29
29
|
const fetch_client_1 = require("./common/net/fetch-client");
|
|
30
30
|
const widgets_1 = require("./widgets/widgets");
|
|
31
31
|
const actions_1 = require("./actions/actions");
|
|
32
|
-
const
|
|
32
|
+
const vault_1 = require("./vault/vault");
|
|
33
|
+
const conflict_exception_1 = require("./common/exceptions/conflict.exception");
|
|
34
|
+
const VERSION = '7.42.0';
|
|
33
35
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
34
36
|
const HEADER_AUTHORIZATION = 'Authorization';
|
|
35
37
|
const HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|
|
@@ -49,6 +51,7 @@ class WorkOS {
|
|
|
49
51
|
this.events = new events_1.Events(this);
|
|
50
52
|
this.fga = new fga_1.FGA(this);
|
|
51
53
|
this.widgets = new widgets_1.Widgets(this);
|
|
54
|
+
this.vault = new vault_1.Vault(this);
|
|
52
55
|
if (!key) {
|
|
53
56
|
// process might be undefined in some environments
|
|
54
57
|
this.key =
|
|
@@ -194,6 +197,9 @@ class WorkOS {
|
|
|
194
197
|
case 401: {
|
|
195
198
|
throw new exceptions_1.UnauthorizedException(requestID);
|
|
196
199
|
}
|
|
200
|
+
case 409: {
|
|
201
|
+
throw new conflict_exception_1.ConflictException({ requestID, message, error });
|
|
202
|
+
}
|
|
197
203
|
case 422: {
|
|
198
204
|
throw new exceptions_1.UnprocessableEntityException({
|
|
199
205
|
code,
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "7.
|
|
2
|
+
"version": "7.42.0",
|
|
3
3
|
"name": "@workos-inc/node",
|
|
4
4
|
"author": "WorkOS",
|
|
5
5
|
"description": "A Node wrapper for the WorkOS API",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"iron-session": "~6.3.1",
|
|
42
42
|
"jose": "~5.6.3",
|
|
43
|
+
"leb": "^1.0.0",
|
|
43
44
|
"pluralize": "8.0.0"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|