@absolutejs/auth 0.55.8 → 0.55.9

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.
@@ -1,5 +1,11 @@
1
1
  export type SecretCipher = {
2
2
  decrypt: (ciphertext: string) => Promise<string>;
3
3
  encrypt: (plaintext: string) => Promise<string>;
4
+ needsReencryption?: (ciphertext: string) => boolean;
4
5
  };
5
6
  export declare const createSecretCipher: (keyMaterial: string) => SecretCipher;
7
+ export declare const createVersionedSecretCipher: ({ currentVersion, keys, legacyKey }: {
8
+ currentVersion: number;
9
+ keys: Readonly<Record<number, string>>;
10
+ legacyKey?: string;
11
+ }) => SecretCipher;
package/dist/index.js CHANGED
@@ -12214,6 +12214,44 @@ var createSecretCipher = (keyMaterial) => ({
12214
12214
  decrypt: (ciphertext) => decryptSecret(ciphertext, keyMaterial),
12215
12215
  encrypt: (plaintext) => encryptSecret(plaintext, keyMaterial)
12216
12216
  });
12217
+ var VERSIONED_CIPHERTEXT_PREFIX = "absolute-vault";
12218
+ var VERSIONED_CIPHERTEXT_SEGMENTS = 3;
12219
+ var parseVersionedCiphertext = (value) => {
12220
+ const [prefix, encodedVersion, ciphertext] = value.split(":", VERSIONED_CIPHERTEXT_SEGMENTS);
12221
+ if (prefix !== VERSIONED_CIPHERTEXT_PREFIX || !encodedVersion || !ciphertext)
12222
+ return null;
12223
+ const version = Number(encodedVersion);
12224
+ if (!Number.isSafeInteger(version) || version < 1)
12225
+ return null;
12226
+ return { ciphertext, version };
12227
+ };
12228
+ var createVersionedSecretCipher = ({
12229
+ currentVersion,
12230
+ keys,
12231
+ legacyKey
12232
+ }) => {
12233
+ if (!Number.isSafeInteger(currentVersion) || currentVersion < 1)
12234
+ throw new Error("Vault key version must be a positive integer");
12235
+ const currentKey = keys[currentVersion];
12236
+ if (!currentKey)
12237
+ throw new Error(`Vault key version ${currentVersion} is unavailable`);
12238
+ return {
12239
+ decrypt: async (value) => {
12240
+ const envelope = parseVersionedCiphertext(value);
12241
+ if (!envelope) {
12242
+ if (!legacyKey)
12243
+ throw new Error("Legacy vault ciphertext key is unavailable");
12244
+ return decryptSecret(value, legacyKey);
12245
+ }
12246
+ const key = keys[envelope.version];
12247
+ if (!key)
12248
+ throw new Error(`Vault key version ${envelope.version} is unavailable`);
12249
+ return decryptSecret(envelope.ciphertext, key);
12250
+ },
12251
+ encrypt: async (plaintext) => `${VERSIONED_CIPHERTEXT_PREFIX}:${currentVersion}:${await encryptSecret(plaintext, currentKey)}`,
12252
+ needsReencryption: (value) => parseVersionedCiphertext(value)?.version !== currentVersion
12253
+ };
12254
+ };
12217
12255
 
12218
12256
  // src/vault/config.ts
12219
12257
  var createVault = ({
@@ -12225,7 +12263,15 @@ var createVault = ({
12225
12263
  const entry = await store.getEntry(ownerId, name);
12226
12264
  if (entry === undefined)
12227
12265
  return;
12228
- return cipher.decrypt(entry.encryptedValue);
12266
+ const plaintext = await cipher.decrypt(entry.encryptedValue);
12267
+ if (cipher.needsReencryption?.(entry.encryptedValue)) {
12268
+ await store.saveEntry({
12269
+ ...entry,
12270
+ encryptedValue: await cipher.encrypt(plaintext),
12271
+ updatedAt: Date.now()
12272
+ });
12273
+ }
12274
+ return plaintext;
12229
12275
  },
12230
12276
  list: async (ownerId) => (await store.listEntries(ownerId)).map((entry) => entry.name),
12231
12277
  put: async (ownerId, name, value) => {
@@ -12249,11 +12295,12 @@ var rotateVaultKey = async ({
12249
12295
  const newCipher = createSecretCipher(newKey);
12250
12296
  const entries = await store.listAllEntries();
12251
12297
  const now = Date.now();
12252
- for (const entry of entries) {
12298
+ await entries.reduce(async (pending, entry) => {
12299
+ await pending;
12253
12300
  const plaintext = await oldCipher.decrypt(entry.encryptedValue);
12254
12301
  const encryptedValue = await newCipher.encrypt(plaintext);
12255
12302
  await store.saveEntry({ ...entry, encryptedValue, updatedAt: now });
12256
- }
12303
+ }, Promise.resolve());
12257
12304
  return { rotated: entries.length };
12258
12305
  };
12259
12306
  // src/vault/inMemoryVaultStore.ts
@@ -30084,5 +30131,5 @@ export {
30084
30131
  AGENT_CLAIM_GRANT_TYPE
30085
30132
  };
30086
30133
 
30087
- //# debugId=DCA509B790E265BD64756E2164756E21
30134
+ //# debugId=A4FF719AF12981EA64756E2164756E21
30088
30135
  //# sourceMappingURL=index.js.map