@meistrari/vault-sdk 1.4.3 → 1.5.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/dist/index.cjs +144 -1
- package/dist/index.d.cts +31 -1
- package/dist/index.d.mts +31 -1
- package/dist/index.d.ts +31 -1
- package/dist/index.mjs +141 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -200,6 +200,69 @@ async function detectFileMimeType(blob) {
|
|
|
200
200
|
return void 0;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
const name = "@meistrari/vault-sdk";
|
|
204
|
+
const version = "1.5.0";
|
|
205
|
+
const license = "UNLICENSED";
|
|
206
|
+
const repository = {
|
|
207
|
+
type: "git",
|
|
208
|
+
url: "https://github.com/meistrari/vault.git"
|
|
209
|
+
};
|
|
210
|
+
const exports$1 = {
|
|
211
|
+
".": {
|
|
212
|
+
types: "./dist/index.d.ts",
|
|
213
|
+
"import": "./dist/index.mjs",
|
|
214
|
+
require: "./dist/index.cjs"
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
const main = "dist/index.mjs";
|
|
218
|
+
const types = "dist/index.d.ts";
|
|
219
|
+
const files = [
|
|
220
|
+
"dist"
|
|
221
|
+
];
|
|
222
|
+
const scripts = {
|
|
223
|
+
test: "vitest --no-watch",
|
|
224
|
+
"test:watch": "vitest",
|
|
225
|
+
build: "unbuild",
|
|
226
|
+
lint: "eslint .",
|
|
227
|
+
"lint:fix": "eslint . --fix",
|
|
228
|
+
check: "bun run lint && bun tsc --noEmit"
|
|
229
|
+
};
|
|
230
|
+
const dependencies = {
|
|
231
|
+
"@meistrari/vault-shared": "workspace:*",
|
|
232
|
+
"file-type": "21.0.0",
|
|
233
|
+
"mime-types": "3.0.1",
|
|
234
|
+
ofetch: "1.4.1",
|
|
235
|
+
zod: "3.23.8"
|
|
236
|
+
};
|
|
237
|
+
const devDependencies = {
|
|
238
|
+
"@types/bun": "latest",
|
|
239
|
+
"@types/mime-types": "3.0.1",
|
|
240
|
+
msw: "2.6.8",
|
|
241
|
+
unbuild: "2.0.0",
|
|
242
|
+
vitest: "2.1.9"
|
|
243
|
+
};
|
|
244
|
+
const peerDependencies = {
|
|
245
|
+
typescript: "^5.0.0"
|
|
246
|
+
};
|
|
247
|
+
const publishConfig = {
|
|
248
|
+
access: "public"
|
|
249
|
+
};
|
|
250
|
+
const packageJson = {
|
|
251
|
+
name: name,
|
|
252
|
+
version: version,
|
|
253
|
+
license: license,
|
|
254
|
+
repository: repository,
|
|
255
|
+
exports: exports$1,
|
|
256
|
+
main: main,
|
|
257
|
+
types: types,
|
|
258
|
+
files: files,
|
|
259
|
+
scripts: scripts,
|
|
260
|
+
dependencies: dependencies,
|
|
261
|
+
devDependencies: devDependencies,
|
|
262
|
+
peerDependencies: peerDependencies,
|
|
263
|
+
publishConfig: publishConfig
|
|
264
|
+
};
|
|
265
|
+
|
|
203
266
|
var __defProp = Object.defineProperty;
|
|
204
267
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
205
268
|
var __publicField = (obj, key, value) => {
|
|
@@ -212,6 +275,7 @@ function removeVaultPrefix(url) {
|
|
|
212
275
|
}
|
|
213
276
|
async function wrappedFetch(...params) {
|
|
214
277
|
const request = new Request(...params);
|
|
278
|
+
request.headers.set("User-Agent", `vault-js-sdk:${packageJson.version}`);
|
|
215
279
|
const response = await fetch(request);
|
|
216
280
|
if (!response.ok) {
|
|
217
281
|
throw await FetchError.from(request.url, request.method, response);
|
|
@@ -253,7 +317,9 @@ class VaultFile {
|
|
|
253
317
|
* @returns The headers for the request
|
|
254
318
|
*/
|
|
255
319
|
get headers() {
|
|
256
|
-
|
|
320
|
+
const headers = this.config.authStrategy.getHeaders();
|
|
321
|
+
headers.set("User-Agent", `vault-js-sdk:${packageJson.version}`);
|
|
322
|
+
return headers;
|
|
257
323
|
}
|
|
258
324
|
/**
|
|
259
325
|
* Performs a request to the vault service and handles the response or errors.
|
|
@@ -679,6 +745,79 @@ class VaultFile {
|
|
|
679
745
|
}
|
|
680
746
|
}
|
|
681
747
|
|
|
748
|
+
function isS3UrlExpired(url) {
|
|
749
|
+
try {
|
|
750
|
+
const urlObj = new URL(url);
|
|
751
|
+
const amzDate = urlObj.searchParams.get("X-Amz-Date");
|
|
752
|
+
const amzExpires = urlObj.searchParams.get("X-Amz-Expires");
|
|
753
|
+
if (!amzDate || !amzExpires)
|
|
754
|
+
return false;
|
|
755
|
+
const year = Number.parseInt(amzDate.substring(0, 4));
|
|
756
|
+
const month = Number.parseInt(amzDate.substring(4, 6)) - 1;
|
|
757
|
+
const day = Number.parseInt(amzDate.substring(6, 8));
|
|
758
|
+
const hours = Number.parseInt(amzDate.substring(9, 11));
|
|
759
|
+
const minutes = Number.parseInt(amzDate.substring(11, 13));
|
|
760
|
+
const seconds = Number.parseInt(amzDate.substring(13, 15));
|
|
761
|
+
const signedDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
|
|
762
|
+
const expiresInSeconds = Number.parseInt(amzExpires);
|
|
763
|
+
const expirationTime = signedDate.getTime() + expiresInSeconds * 1e3;
|
|
764
|
+
const currentTime = Date.now();
|
|
765
|
+
return currentTime > expirationTime;
|
|
766
|
+
} catch {
|
|
767
|
+
return false;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
function isVaultReference(url) {
|
|
771
|
+
return url.startsWith("vault://") && url.length === 10;
|
|
772
|
+
}
|
|
773
|
+
function isVaultFileS3Url(url) {
|
|
774
|
+
const urlObj = new URL(url);
|
|
775
|
+
const amzDate = urlObj.searchParams.get("X-Amz-Date");
|
|
776
|
+
const amzExpires = urlObj.searchParams.get("X-Amz-Expires");
|
|
777
|
+
return urlObj.hostname.includes("amazonaws.com") && Boolean(amzDate) && Boolean(amzExpires);
|
|
778
|
+
}
|
|
779
|
+
const URL_STRATEGIES = [
|
|
780
|
+
{
|
|
781
|
+
separator: "/",
|
|
782
|
+
extractSegments: ([workspaceId, vaultFileId]) => ({
|
|
783
|
+
workspaceId,
|
|
784
|
+
vaultFileId
|
|
785
|
+
})
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
separator: "_",
|
|
789
|
+
extractSegments: ([vaultFileId, workspaceId]) => ({
|
|
790
|
+
vaultFileId,
|
|
791
|
+
workspaceId
|
|
792
|
+
})
|
|
793
|
+
}
|
|
794
|
+
];
|
|
795
|
+
function extractVaultFileIdFromS3Url(url) {
|
|
796
|
+
if (isVaultReference(url))
|
|
797
|
+
return url.replace("vault://", "");
|
|
798
|
+
try {
|
|
799
|
+
if (!isVaultFileS3Url(url))
|
|
800
|
+
return null;
|
|
801
|
+
const urlObj = new URL(url);
|
|
802
|
+
const strategy = URL_STRATEGIES.find((strategy2) => urlObj.pathname.includes(strategy2.separator));
|
|
803
|
+
if (!strategy)
|
|
804
|
+
return null;
|
|
805
|
+
const segments = urlObj.pathname.split(strategy.separator).filter((segment) => segment.length > 0);
|
|
806
|
+
if (segments.length < 2)
|
|
807
|
+
return null;
|
|
808
|
+
const extractedIds = strategy.extractSegments(segments);
|
|
809
|
+
if (!extractedIds || !extractedIds.vaultFileId || !extractedIds.workspaceId || extractedIds.vaultFileId.length < 32)
|
|
810
|
+
return null;
|
|
811
|
+
return extractedIds.vaultFileId;
|
|
812
|
+
} catch {
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
function convertS3UrlToVaultReference(url) {
|
|
817
|
+
const vaultFileId = extractVaultFileIdFromS3Url(url);
|
|
818
|
+
return vaultFileId ? `vault://${vaultFileId}` : null;
|
|
819
|
+
}
|
|
820
|
+
|
|
682
821
|
function vaultClient(vaultConfig) {
|
|
683
822
|
const config = resolveConfig(vaultConfig);
|
|
684
823
|
function createFromContent(name, content, options) {
|
|
@@ -701,4 +840,8 @@ exports.APIKeyAuthStrategy = APIKeyAuthStrategy;
|
|
|
701
840
|
exports.DataTokenAuthStrategy = DataTokenAuthStrategy;
|
|
702
841
|
exports.FetchError = FetchError;
|
|
703
842
|
exports.VaultFile = VaultFile;
|
|
843
|
+
exports.convertS3UrlToVaultReference = convertS3UrlToVaultReference;
|
|
844
|
+
exports.extractVaultFileIdFromS3Url = extractVaultFileIdFromS3Url;
|
|
845
|
+
exports.isS3UrlExpired = isS3UrlExpired;
|
|
846
|
+
exports.isVaultFileS3Url = isVaultFileS3Url;
|
|
704
847
|
exports.vaultClient = vaultClient;
|
package/dist/index.d.cts
CHANGED
|
@@ -399,6 +399,36 @@ declare class VaultFile {
|
|
|
399
399
|
}): Promise<Permalink[]>;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
+
/**
|
|
403
|
+
* Checks if an Amazon S3 signed URL has expired
|
|
404
|
+
* @param url - The S3 URL to check for expiration
|
|
405
|
+
* @returns true if the URL is expired, false if it's still valid or not an S3 signed URL
|
|
406
|
+
* @example
|
|
407
|
+
* const expired = isS3UrlExpired('https://vault-prod.s3.amazonaws.com/file?X-Amz-Date=20240101T000000Z&X-Amz-Expires=3600')
|
|
408
|
+
*/
|
|
409
|
+
declare function isS3UrlExpired(url: string): boolean;
|
|
410
|
+
/**
|
|
411
|
+
* Checks if a URL is a valid S3 vault URL
|
|
412
|
+
* @param url - The S3 URL to check
|
|
413
|
+
* @returns true if the URL is a valid S3 vault URL, false otherwise
|
|
414
|
+
*/
|
|
415
|
+
declare function isVaultFileS3Url(url: string): boolean;
|
|
416
|
+
/**
|
|
417
|
+
* Detects if a URL is an expired S3 vault URL and extracts the vault file ID
|
|
418
|
+
* Returns null if not a vault S3 URL, not expired, or extraction fails
|
|
419
|
+
*/
|
|
420
|
+
declare function extractVaultFileIdFromS3Url(url: string): string | null;
|
|
421
|
+
/**
|
|
422
|
+
* Converts an S3 vault URL to a vault reference format
|
|
423
|
+
* Extracts the vault file ID from the S3 URL path and formats it as vault://[fileId]
|
|
424
|
+
* @param url - The S3 vault URL to convert
|
|
425
|
+
* @returns A vault reference string (vault://[fileId]) if successful, null if the URL is not a valid vault S3 URL
|
|
426
|
+
* @example
|
|
427
|
+
* const ref = convertS3UrlToVaultReference('https://vault-prod.s3.amazonaws.com/workspace123/2fce574083da49fe3f10b32205893ec0bb024fe1c7673fa54927fdfe1d0db9d6?...')
|
|
428
|
+
* // Returns: 'vault://2fce574083da49fe3f10b32205893ec0bb024fe1c7673fa54927fdfe1d0db9d6'
|
|
429
|
+
*/
|
|
430
|
+
declare function convertS3UrlToVaultReference(url: string): string | null;
|
|
431
|
+
|
|
402
432
|
declare function vaultClient(vaultConfig: VaultConfig): {
|
|
403
433
|
createFromContent: (name: string, content: Blob | File, options?: {
|
|
404
434
|
signal?: AbortSignal;
|
|
@@ -408,5 +438,5 @@ declare function vaultClient(vaultConfig: VaultConfig): {
|
|
|
408
438
|
}) => Promise<VaultFile>;
|
|
409
439
|
};
|
|
410
440
|
|
|
411
|
-
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
|
|
441
|
+
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, convertS3UrlToVaultReference, extractVaultFileIdFromS3Url, isS3UrlExpired, isVaultFileS3Url, vaultClient };
|
|
412
442
|
export type { AuthStrategy, VaultConfig };
|
package/dist/index.d.mts
CHANGED
|
@@ -399,6 +399,36 @@ declare class VaultFile {
|
|
|
399
399
|
}): Promise<Permalink[]>;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
+
/**
|
|
403
|
+
* Checks if an Amazon S3 signed URL has expired
|
|
404
|
+
* @param url - The S3 URL to check for expiration
|
|
405
|
+
* @returns true if the URL is expired, false if it's still valid or not an S3 signed URL
|
|
406
|
+
* @example
|
|
407
|
+
* const expired = isS3UrlExpired('https://vault-prod.s3.amazonaws.com/file?X-Amz-Date=20240101T000000Z&X-Amz-Expires=3600')
|
|
408
|
+
*/
|
|
409
|
+
declare function isS3UrlExpired(url: string): boolean;
|
|
410
|
+
/**
|
|
411
|
+
* Checks if a URL is a valid S3 vault URL
|
|
412
|
+
* @param url - The S3 URL to check
|
|
413
|
+
* @returns true if the URL is a valid S3 vault URL, false otherwise
|
|
414
|
+
*/
|
|
415
|
+
declare function isVaultFileS3Url(url: string): boolean;
|
|
416
|
+
/**
|
|
417
|
+
* Detects if a URL is an expired S3 vault URL and extracts the vault file ID
|
|
418
|
+
* Returns null if not a vault S3 URL, not expired, or extraction fails
|
|
419
|
+
*/
|
|
420
|
+
declare function extractVaultFileIdFromS3Url(url: string): string | null;
|
|
421
|
+
/**
|
|
422
|
+
* Converts an S3 vault URL to a vault reference format
|
|
423
|
+
* Extracts the vault file ID from the S3 URL path and formats it as vault://[fileId]
|
|
424
|
+
* @param url - The S3 vault URL to convert
|
|
425
|
+
* @returns A vault reference string (vault://[fileId]) if successful, null if the URL is not a valid vault S3 URL
|
|
426
|
+
* @example
|
|
427
|
+
* const ref = convertS3UrlToVaultReference('https://vault-prod.s3.amazonaws.com/workspace123/2fce574083da49fe3f10b32205893ec0bb024fe1c7673fa54927fdfe1d0db9d6?...')
|
|
428
|
+
* // Returns: 'vault://2fce574083da49fe3f10b32205893ec0bb024fe1c7673fa54927fdfe1d0db9d6'
|
|
429
|
+
*/
|
|
430
|
+
declare function convertS3UrlToVaultReference(url: string): string | null;
|
|
431
|
+
|
|
402
432
|
declare function vaultClient(vaultConfig: VaultConfig): {
|
|
403
433
|
createFromContent: (name: string, content: Blob | File, options?: {
|
|
404
434
|
signal?: AbortSignal;
|
|
@@ -408,5 +438,5 @@ declare function vaultClient(vaultConfig: VaultConfig): {
|
|
|
408
438
|
}) => Promise<VaultFile>;
|
|
409
439
|
};
|
|
410
440
|
|
|
411
|
-
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
|
|
441
|
+
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, convertS3UrlToVaultReference, extractVaultFileIdFromS3Url, isS3UrlExpired, isVaultFileS3Url, vaultClient };
|
|
412
442
|
export type { AuthStrategy, VaultConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -399,6 +399,36 @@ declare class VaultFile {
|
|
|
399
399
|
}): Promise<Permalink[]>;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
+
/**
|
|
403
|
+
* Checks if an Amazon S3 signed URL has expired
|
|
404
|
+
* @param url - The S3 URL to check for expiration
|
|
405
|
+
* @returns true if the URL is expired, false if it's still valid or not an S3 signed URL
|
|
406
|
+
* @example
|
|
407
|
+
* const expired = isS3UrlExpired('https://vault-prod.s3.amazonaws.com/file?X-Amz-Date=20240101T000000Z&X-Amz-Expires=3600')
|
|
408
|
+
*/
|
|
409
|
+
declare function isS3UrlExpired(url: string): boolean;
|
|
410
|
+
/**
|
|
411
|
+
* Checks if a URL is a valid S3 vault URL
|
|
412
|
+
* @param url - The S3 URL to check
|
|
413
|
+
* @returns true if the URL is a valid S3 vault URL, false otherwise
|
|
414
|
+
*/
|
|
415
|
+
declare function isVaultFileS3Url(url: string): boolean;
|
|
416
|
+
/**
|
|
417
|
+
* Detects if a URL is an expired S3 vault URL and extracts the vault file ID
|
|
418
|
+
* Returns null if not a vault S3 URL, not expired, or extraction fails
|
|
419
|
+
*/
|
|
420
|
+
declare function extractVaultFileIdFromS3Url(url: string): string | null;
|
|
421
|
+
/**
|
|
422
|
+
* Converts an S3 vault URL to a vault reference format
|
|
423
|
+
* Extracts the vault file ID from the S3 URL path and formats it as vault://[fileId]
|
|
424
|
+
* @param url - The S3 vault URL to convert
|
|
425
|
+
* @returns A vault reference string (vault://[fileId]) if successful, null if the URL is not a valid vault S3 URL
|
|
426
|
+
* @example
|
|
427
|
+
* const ref = convertS3UrlToVaultReference('https://vault-prod.s3.amazonaws.com/workspace123/2fce574083da49fe3f10b32205893ec0bb024fe1c7673fa54927fdfe1d0db9d6?...')
|
|
428
|
+
* // Returns: 'vault://2fce574083da49fe3f10b32205893ec0bb024fe1c7673fa54927fdfe1d0db9d6'
|
|
429
|
+
*/
|
|
430
|
+
declare function convertS3UrlToVaultReference(url: string): string | null;
|
|
431
|
+
|
|
402
432
|
declare function vaultClient(vaultConfig: VaultConfig): {
|
|
403
433
|
createFromContent: (name: string, content: Blob | File, options?: {
|
|
404
434
|
signal?: AbortSignal;
|
|
@@ -408,5 +438,5 @@ declare function vaultClient(vaultConfig: VaultConfig): {
|
|
|
408
438
|
}) => Promise<VaultFile>;
|
|
409
439
|
};
|
|
410
440
|
|
|
411
|
-
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
|
|
441
|
+
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, convertS3UrlToVaultReference, extractVaultFileIdFromS3Url, isS3UrlExpired, isVaultFileS3Url, vaultClient };
|
|
412
442
|
export type { AuthStrategy, VaultConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -198,6 +198,69 @@ async function detectFileMimeType(blob) {
|
|
|
198
198
|
return void 0;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
const name = "@meistrari/vault-sdk";
|
|
202
|
+
const version = "1.5.0";
|
|
203
|
+
const license = "UNLICENSED";
|
|
204
|
+
const repository = {
|
|
205
|
+
type: "git",
|
|
206
|
+
url: "https://github.com/meistrari/vault.git"
|
|
207
|
+
};
|
|
208
|
+
const exports = {
|
|
209
|
+
".": {
|
|
210
|
+
types: "./dist/index.d.ts",
|
|
211
|
+
"import": "./dist/index.mjs",
|
|
212
|
+
require: "./dist/index.cjs"
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const main = "dist/index.mjs";
|
|
216
|
+
const types = "dist/index.d.ts";
|
|
217
|
+
const files = [
|
|
218
|
+
"dist"
|
|
219
|
+
];
|
|
220
|
+
const scripts = {
|
|
221
|
+
test: "vitest --no-watch",
|
|
222
|
+
"test:watch": "vitest",
|
|
223
|
+
build: "unbuild",
|
|
224
|
+
lint: "eslint .",
|
|
225
|
+
"lint:fix": "eslint . --fix",
|
|
226
|
+
check: "bun run lint && bun tsc --noEmit"
|
|
227
|
+
};
|
|
228
|
+
const dependencies = {
|
|
229
|
+
"@meistrari/vault-shared": "workspace:*",
|
|
230
|
+
"file-type": "21.0.0",
|
|
231
|
+
"mime-types": "3.0.1",
|
|
232
|
+
ofetch: "1.4.1",
|
|
233
|
+
zod: "3.23.8"
|
|
234
|
+
};
|
|
235
|
+
const devDependencies = {
|
|
236
|
+
"@types/bun": "latest",
|
|
237
|
+
"@types/mime-types": "3.0.1",
|
|
238
|
+
msw: "2.6.8",
|
|
239
|
+
unbuild: "2.0.0",
|
|
240
|
+
vitest: "2.1.9"
|
|
241
|
+
};
|
|
242
|
+
const peerDependencies = {
|
|
243
|
+
typescript: "^5.0.0"
|
|
244
|
+
};
|
|
245
|
+
const publishConfig = {
|
|
246
|
+
access: "public"
|
|
247
|
+
};
|
|
248
|
+
const packageJson = {
|
|
249
|
+
name: name,
|
|
250
|
+
version: version,
|
|
251
|
+
license: license,
|
|
252
|
+
repository: repository,
|
|
253
|
+
exports: exports,
|
|
254
|
+
main: main,
|
|
255
|
+
types: types,
|
|
256
|
+
files: files,
|
|
257
|
+
scripts: scripts,
|
|
258
|
+
dependencies: dependencies,
|
|
259
|
+
devDependencies: devDependencies,
|
|
260
|
+
peerDependencies: peerDependencies,
|
|
261
|
+
publishConfig: publishConfig
|
|
262
|
+
};
|
|
263
|
+
|
|
201
264
|
var __defProp = Object.defineProperty;
|
|
202
265
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
203
266
|
var __publicField = (obj, key, value) => {
|
|
@@ -210,6 +273,7 @@ function removeVaultPrefix(url) {
|
|
|
210
273
|
}
|
|
211
274
|
async function wrappedFetch(...params) {
|
|
212
275
|
const request = new Request(...params);
|
|
276
|
+
request.headers.set("User-Agent", `vault-js-sdk:${packageJson.version}`);
|
|
213
277
|
const response = await fetch(request);
|
|
214
278
|
if (!response.ok) {
|
|
215
279
|
throw await FetchError.from(request.url, request.method, response);
|
|
@@ -251,7 +315,9 @@ class VaultFile {
|
|
|
251
315
|
* @returns The headers for the request
|
|
252
316
|
*/
|
|
253
317
|
get headers() {
|
|
254
|
-
|
|
318
|
+
const headers = this.config.authStrategy.getHeaders();
|
|
319
|
+
headers.set("User-Agent", `vault-js-sdk:${packageJson.version}`);
|
|
320
|
+
return headers;
|
|
255
321
|
}
|
|
256
322
|
/**
|
|
257
323
|
* Performs a request to the vault service and handles the response or errors.
|
|
@@ -677,6 +743,79 @@ class VaultFile {
|
|
|
677
743
|
}
|
|
678
744
|
}
|
|
679
745
|
|
|
746
|
+
function isS3UrlExpired(url) {
|
|
747
|
+
try {
|
|
748
|
+
const urlObj = new URL(url);
|
|
749
|
+
const amzDate = urlObj.searchParams.get("X-Amz-Date");
|
|
750
|
+
const amzExpires = urlObj.searchParams.get("X-Amz-Expires");
|
|
751
|
+
if (!amzDate || !amzExpires)
|
|
752
|
+
return false;
|
|
753
|
+
const year = Number.parseInt(amzDate.substring(0, 4));
|
|
754
|
+
const month = Number.parseInt(amzDate.substring(4, 6)) - 1;
|
|
755
|
+
const day = Number.parseInt(amzDate.substring(6, 8));
|
|
756
|
+
const hours = Number.parseInt(amzDate.substring(9, 11));
|
|
757
|
+
const minutes = Number.parseInt(amzDate.substring(11, 13));
|
|
758
|
+
const seconds = Number.parseInt(amzDate.substring(13, 15));
|
|
759
|
+
const signedDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
|
|
760
|
+
const expiresInSeconds = Number.parseInt(amzExpires);
|
|
761
|
+
const expirationTime = signedDate.getTime() + expiresInSeconds * 1e3;
|
|
762
|
+
const currentTime = Date.now();
|
|
763
|
+
return currentTime > expirationTime;
|
|
764
|
+
} catch {
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function isVaultReference(url) {
|
|
769
|
+
return url.startsWith("vault://") && url.length === 10;
|
|
770
|
+
}
|
|
771
|
+
function isVaultFileS3Url(url) {
|
|
772
|
+
const urlObj = new URL(url);
|
|
773
|
+
const amzDate = urlObj.searchParams.get("X-Amz-Date");
|
|
774
|
+
const amzExpires = urlObj.searchParams.get("X-Amz-Expires");
|
|
775
|
+
return urlObj.hostname.includes("amazonaws.com") && Boolean(amzDate) && Boolean(amzExpires);
|
|
776
|
+
}
|
|
777
|
+
const URL_STRATEGIES = [
|
|
778
|
+
{
|
|
779
|
+
separator: "/",
|
|
780
|
+
extractSegments: ([workspaceId, vaultFileId]) => ({
|
|
781
|
+
workspaceId,
|
|
782
|
+
vaultFileId
|
|
783
|
+
})
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
separator: "_",
|
|
787
|
+
extractSegments: ([vaultFileId, workspaceId]) => ({
|
|
788
|
+
vaultFileId,
|
|
789
|
+
workspaceId
|
|
790
|
+
})
|
|
791
|
+
}
|
|
792
|
+
];
|
|
793
|
+
function extractVaultFileIdFromS3Url(url) {
|
|
794
|
+
if (isVaultReference(url))
|
|
795
|
+
return url.replace("vault://", "");
|
|
796
|
+
try {
|
|
797
|
+
if (!isVaultFileS3Url(url))
|
|
798
|
+
return null;
|
|
799
|
+
const urlObj = new URL(url);
|
|
800
|
+
const strategy = URL_STRATEGIES.find((strategy2) => urlObj.pathname.includes(strategy2.separator));
|
|
801
|
+
if (!strategy)
|
|
802
|
+
return null;
|
|
803
|
+
const segments = urlObj.pathname.split(strategy.separator).filter((segment) => segment.length > 0);
|
|
804
|
+
if (segments.length < 2)
|
|
805
|
+
return null;
|
|
806
|
+
const extractedIds = strategy.extractSegments(segments);
|
|
807
|
+
if (!extractedIds || !extractedIds.vaultFileId || !extractedIds.workspaceId || extractedIds.vaultFileId.length < 32)
|
|
808
|
+
return null;
|
|
809
|
+
return extractedIds.vaultFileId;
|
|
810
|
+
} catch {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
function convertS3UrlToVaultReference(url) {
|
|
815
|
+
const vaultFileId = extractVaultFileIdFromS3Url(url);
|
|
816
|
+
return vaultFileId ? `vault://${vaultFileId}` : null;
|
|
817
|
+
}
|
|
818
|
+
|
|
680
819
|
function vaultClient(vaultConfig) {
|
|
681
820
|
const config = resolveConfig(vaultConfig);
|
|
682
821
|
function createFromContent(name, content, options) {
|
|
@@ -695,4 +834,4 @@ function vaultClient(vaultConfig) {
|
|
|
695
834
|
return { createFromContent, createFromReference };
|
|
696
835
|
}
|
|
697
836
|
|
|
698
|
-
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, vaultClient };
|
|
837
|
+
export { APIKeyAuthStrategy, DataTokenAuthStrategy, FetchError, VaultFile, convertS3UrlToVaultReference, extractVaultFileIdFromS3Url, isS3UrlExpired, isVaultFileS3Url, vaultClient };
|