Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions modules/encryption/define_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { configProvider } from '../../src/config_provider.ts'
import { type ConfigProvider } from '../../src/types.ts'

import {
type AESSIVDriverConfig,
type AES256CBCDriverConfig,
type AES256GCMDriverConfig,
type ChaCha20Poly1305DriverConfig,
Expand Down Expand Up @@ -198,6 +199,21 @@ export const drivers: {
*/
aes256gcm: (config: AES256GCMDriverConfig) => ConfigProvider<EncryptionConfig>

/**
* Creates an AES-SIV encryption driver configuration.
*
* @param config - The AES-SIV driver configuration
*
* @example
* ```ts
* drivers.aessiv({
* id: 'app',
* key: env.get('APP_KEY')
* })
* ```
*/
aessiv: (config: AESSIVDriverConfig) => ConfigProvider<EncryptionConfig>

/**
* Creates a Legacy encryption driver configuration.
*
Expand Down Expand Up @@ -251,6 +267,17 @@ export const drivers: {
})
},

aessiv: (config) => {
return configProvider.create(async () => {
const { AESSIV } = await import('./drivers/aes_siv.ts')
debug('configuring aessiv encryption driver')
return {
driver: (key) => new AESSIV({ id: config.id, key }),
keys: [config.key].filter((key) => !!key),
}
})
},
Comment on lines +270 to +279
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using .filter((key) => !!key) does not reliably narrow the array type in TypeScript, which can leave keys typed as (string | undefined)[] even if EncryptionConfig expects string[]. Use a type-predicate filter (e.g. (key): key is string => Boolean(key)) or avoid filtering entirely if config.key is required.

Copilot uses AI. Check for mistakes.

legacy: (config) => {
return configProvider.create(async () => {
const { Legacy } = await import('./drivers/legacy.ts')
Expand Down
28 changes: 28 additions & 0 deletions modules/encryption/drivers/aes_siv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* @adonisjs/core
*
* (c) AdonisJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

/**
* AES-SIV encryption driver implementation.
*
* This driver provides deterministic authenticated encryption using AES-SIV
* (Synthetic Initialization Vector). It is useful when you need equality
* queries over encrypted values while preserving authenticity guarantees.
*
* @example
* ```ts
* const driver = new AESSIV({
* id: 'app',
* key: 'your-256-bit-key-here'
* })
*
* const encrypted = driver.encrypt('sensitive data')
* const decrypted = driver.decrypt(encrypted)
* ```
*/
export { AESSIV } from '@boringnode/encryption/drivers/aes_siv'
15 changes: 15 additions & 0 deletions modules/encryption/drivers/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
EncryptOptions,
} from '@boringnode/encryption/types'
import { errors } from '@boringnode/encryption'
import { E_LEGACY_BLIND_INDEX_NOT_SUPPORTED } from '../errors.ts'

/**
* Configuration for the Legacy encryption driver.
Expand Down Expand Up @@ -183,4 +184,18 @@ export class Legacy extends BaseDriver implements EncryptionDriverContract {
return null
}
}

/**
* Legacy driver does not support blind indexes.
*/
blindIndex(_payload: any, _purpose: string): string {
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
}

/**
* Legacy driver does not support blind indexes.
*/
blindIndexes(_payload: any, _purpose: string): string[] {
Comment on lines +191 to +198
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using any for _payload weakens type-safety for callers and makes it easier to accidentally pass unsupported values without compiler feedback. If the contract allows it, prefer unknown (or a narrower union) for _payload since the method intentionally does not consume it.

Suggested change
blindIndex(_payload: any, _purpose: string): string {
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
}
/**
* Legacy driver does not support blind indexes.
*/
blindIndexes(_payload: any, _purpose: string): string[] {
blindIndex(_payload: unknown, _purpose: string): string {
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
}
/**
* Legacy driver does not support blind indexes.
*/
blindIndexes(_payload: unknown, _purpose: string): string[] {

Copilot uses AI. Check for mistakes.
Comment on lines +191 to +198
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using any for _payload weakens type-safety for callers and makes it easier to accidentally pass unsupported values without compiler feedback. If the contract allows it, prefer unknown (or a narrower union) for _payload since the method intentionally does not consume it.

Suggested change
blindIndex(_payload: any, _purpose: string): string {
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
}
/**
* Legacy driver does not support blind indexes.
*/
blindIndexes(_payload: any, _purpose: string): string[] {
blindIndex(_payload: unknown, _purpose: string): string {
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
}
/**
* Legacy driver does not support blind indexes.
*/
blindIndexes(_payload: unknown, _purpose: string): string[] {

Copilot uses AI. Check for mistakes.
throw new E_LEGACY_BLIND_INDEX_NOT_SUPPORTED()
}
}
27 changes: 27 additions & 0 deletions modules/encryption/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* @adonisjs/core
*
* (c) AdonisJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { createError } from '../../src/exceptions.ts'
import { errors as boringnodeErrors } from '@boringnode/encryption'

/**
* Raised when attempting to compute blind indexes using the legacy driver.
*/
export const E_LEGACY_BLIND_INDEX_NOT_SUPPORTED = createError(
'Blind indexes are not supported by the legacy encryption driver',
'E_LEGACY_BLIND_INDEX_NOT_SUPPORTED'
)
Comment on lines +16 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be called E_BLIND_INDEX_NOT_SUPPORTED?


/**
* Encryption errors exposed by this package.
*/
export const errors = {
...boringnodeErrors,
E_LEGACY_BLIND_INDEX_NOT_SUPPORTED,
}
9 changes: 7 additions & 2 deletions modules/encryption/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ export { Hmac } from '@boringnode/encryption'
*/
export { BaseDriver } from '@boringnode/encryption'

/**
* Encryption module specific exceptions.
*/
export { errors } from './errors.ts'

/**
* Defines the encryption configuration for the application.
*
Expand All @@ -91,8 +96,8 @@ export { defineConfig } from './define_config.ts'
/**
* Collection of built-in encryption driver factory functions.
*
* Includes factories for ChaCha20-Poly1305, AES-256-CBC, and
* AES-256-GCM encryption algorithms.
* Includes factories for ChaCha20-Poly1305, AES-256-CBC,
* AES-256-GCM, and AES-SIV encryption algorithms.
*
* @see {drivers} in define_config.ts for detailed documentation
*/
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"./encryption": "./build/modules/encryption/main.js",
"./encryption/drivers/aes_256_cbc": "./build/modules/encryption/drivers/aes_256_cbc.js",
"./encryption/drivers/aes_256_gcm": "./build/modules/encryption/drivers/aes_256_gcm.js",
"./encryption/drivers/aes_siv": "./build/modules/encryption/drivers/aes_siv.js",
"./encryption/drivers/chacha20_poly1305": "./build/modules/encryption/drivers/chacha20_poly1305.js",
"./env": "./build/modules/env/main.js",
"./dumper": "./build/modules/dumper/main.js",
Expand Down Expand Up @@ -129,7 +130,7 @@
"@adonisjs/fold": "^11.0.0-next.4",
"@adonisjs/hash": "^10.0.0-next.2",
"@adonisjs/health": "^3.1.0-next.1",
"@adonisjs/http-server": "^8.0.0-next.18",
"@adonisjs/http-server": "^8.0.0-next.19",
"@adonisjs/http-transformers": "^2.2.0",
"@adonisjs/logger": "^7.1.0-next.3",
"@adonisjs/repl": "^5.0.0-next.2",
Expand Down
20 changes: 20 additions & 0 deletions tests/encryption/legacy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,23 @@ test.group('Legacy | defineConfig', () => {
assert.deepEqual(config.list.legacy.keys, [SECRET_KEY])
})
})

test.group('Legacy | blind indexes', () => {
test('throw when computing blind index', ({ assert }) => {
const encryption = new Legacy({ key: SECRET_KEY })

assert.throws(
() => encryption.blindIndex('foo@example.com', 'users.email'),
'Blind indexes are not supported by the legacy encryption driver'
)
Comment on lines +280 to +283
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this assert is Node.js-style (or Node-compatible), passing a string as the 2nd argument is treated as the assertion message (used when the assertion fails), not as a matcher for the thrown error message. This means these tests may not actually validate the thrown error details. Prefer matching the thrown error via a RegExp / error constructor / { message: ... } object so the test asserts the correct failure mode.

Copilot uses AI. Check for mistakes.
})

test('throw when computing blind indexes', ({ assert }) => {
const encryption = new Legacy({ key: SECRET_KEY })

assert.throws(
() => encryption.blindIndexes('foo@example.com', 'users.email'),
'Blind indexes are not supported by the legacy encryption driver'
)
Comment on lines +289 to +292
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this assert is Node.js-style (or Node-compatible), passing a string as the 2nd argument is treated as the assertion message (used when the assertion fails), not as a matcher for the thrown error message. This means these tests may not actually validate the thrown error details. Prefer matching the thrown error via a RegExp / error constructor / { message: ... } object so the test asserts the correct failure mode.

Copilot uses AI. Check for mistakes.
})
})
7 changes: 7 additions & 0 deletions types/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ export type { AES256CBCDriverConfig } from '@boringnode/encryption/drivers/aes_2
*/
export type { AES256GCMDriverConfig } from '@boringnode/encryption/drivers/aes_256_gcm'

/**
* Configuration options for the AES-SIV encryption driver.
*
* Includes the driver identifier and a single encryption key.
*/
export type { AESSIVDriverConfig } from '@boringnode/encryption/drivers/aes_siv'

/**
* Configuration options for the ChaCha20-Poly1305 encryption driver.
*
Expand Down
Loading