asherah 3.0.16 → 4.0.0-beta.10
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/README.md +25 -162
- package/index.d.ts +102 -0
- package/npm/index.js +230 -0
- package/package.json +38 -76
- package/.asherah-version +0 -1
- package/LICENSE +0 -21
- package/SHA256SUMS +0 -12
- package/SHA256SUMS-darwin +0 -12
- package/binding.gyp +0 -36
- package/scripts/build.sh +0 -16
- package/scripts/download-libraries.sh +0 -322
- package/src/asherah.cc +0 -792
- package/src/asherah.d.ts +0 -65
- package/src/asherah_async_worker.h +0 -60
- package/src/cobhan_buffer.h +0 -260
- package/src/cobhan_buffer_napi.h +0 -218
- package/src/hints.h +0 -7
- package/src/logging.h +0 -49
- package/src/logging_napi.cc +0 -115
- package/src/logging_napi.h +0 -41
- package/src/logging_stderr.cc +0 -60
- package/src/logging_stderr.h +0 -23
- package/src/napi_utils.h +0 -164
- package/src/scoped_allocate.h +0 -50
package/README.md
CHANGED
|
@@ -1,179 +1,42 @@
|
|
|
1
|
-
# asherah
|
|
1
|
+
# asherah
|
|
2
2
|
|
|
3
|
-
Asherah envelope encryption and key rotation library
|
|
3
|
+
Node.js bindings for the Asherah envelope encryption and key rotation library.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Prebuilt native binaries are published to npm for Linux (x64/arm64, glibc and
|
|
6
|
+
musl), macOS (x64/arm64), and Windows (x64/arm64). The correct binary is
|
|
7
|
+
selected automatically at install time.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## Features
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
- Synchronous and asynchronous encrypt/decrypt APIs
|
|
12
|
+
- Compatible with Go, Python, Ruby, Java, and .NET Asherah implementations
|
|
13
|
+
- SQLite, MySQL, PostgreSQL, and DynamoDB metastore support
|
|
14
|
+
- AWS KMS and static key management
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
## Installation
|
|
12
17
|
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const config: AsherahConfig = {
|
|
17
|
-
KMS: 'aws',
|
|
18
|
-
Metastore: 'memory',
|
|
19
|
-
ServiceName: 'TestService',
|
|
20
|
-
ProductID: 'TestProduct',
|
|
21
|
-
Verbose: true,
|
|
22
|
-
EnableSessionCaching: true,
|
|
23
|
-
ExpireAfter: null,
|
|
24
|
-
CheckInterval: null,
|
|
25
|
-
ConnectionString: null,
|
|
26
|
-
ReplicaReadConsistency: null,
|
|
27
|
-
DynamoDBEndpoint: null,
|
|
28
|
-
DynamoDBRegion: null,
|
|
29
|
-
DynamoDBTableName: null,
|
|
30
|
-
SessionCacheMaxSize: null,
|
|
31
|
-
SessionCacheDuration: null,
|
|
32
|
-
RegionMap: {"us-west-2": "arn:aws:kms:us-west-2:XXXXXXXXX:key/XXXXXXXXXX"},
|
|
33
|
-
PreferredRegion: null,
|
|
34
|
-
EnableRegionSuffix: null,
|
|
35
|
-
DisableZeroCopy: null
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
setup(config)
|
|
39
|
-
|
|
40
|
-
const input = 'mysecretdata'
|
|
41
|
-
|
|
42
|
-
console.log("Input: " + input)
|
|
43
|
-
|
|
44
|
-
const data = Buffer.from(input, 'utf8');
|
|
45
|
-
|
|
46
|
-
const encrypted = encrypt('partition', data);
|
|
47
|
-
|
|
48
|
-
const decrypted = decrypt('partition', encrypted);
|
|
49
|
-
|
|
50
|
-
const output = decrypted.toString('utf8');
|
|
51
|
-
|
|
52
|
-
console.log("Output: " + output)
|
|
53
|
-
|
|
54
|
-
shutdown()
|
|
18
|
+
```bash
|
|
19
|
+
npm install asherah
|
|
55
20
|
```
|
|
56
21
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```javascript
|
|
60
|
-
|
|
61
|
-
const asherah = require('asherah')
|
|
62
|
-
|
|
63
|
-
const config = {
|
|
64
|
-
KMS: 'aws',
|
|
65
|
-
Metastore: 'memory',
|
|
66
|
-
ServiceName: 'TestService',
|
|
67
|
-
ProductID: 'TestProduct',
|
|
68
|
-
Verbose: true,
|
|
69
|
-
EnableSessionCaching: true,
|
|
70
|
-
ExpireAfter: null,
|
|
71
|
-
CheckInterval: null,
|
|
72
|
-
ConnectionString: null,
|
|
73
|
-
ReplicaReadConsistency: null,
|
|
74
|
-
DynamoDBEndpoint: null,
|
|
75
|
-
DynamoDBRegion: null,
|
|
76
|
-
DynamoDBTableName: null,
|
|
77
|
-
SessionCacheMaxSize: null,
|
|
78
|
-
SessionCacheDuration: null,
|
|
79
|
-
RegionMap: {"us-west-2": "arn:aws:kms:us-west-2:XXXXXXXXX:key/XXXXXXXXXX"},
|
|
80
|
-
PreferredRegion: null,
|
|
81
|
-
EnableRegionSuffix: null,
|
|
82
|
-
DisableZeroCopy: null
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
asherah.setup(config)
|
|
86
|
-
|
|
87
|
-
const input = 'mysecretdata'
|
|
88
|
-
|
|
89
|
-
console.log("Input: " + input)
|
|
90
|
-
|
|
91
|
-
const data = Buffer.from(input, 'utf8');
|
|
92
|
-
|
|
93
|
-
const encrypted = asherah.encrypt('partition', data);
|
|
94
|
-
|
|
95
|
-
const decrypted = asherah.decrypt('partition', encrypted);
|
|
96
|
-
|
|
97
|
-
const output = decrypted.toString('utf8');
|
|
98
|
-
|
|
99
|
-
console.log("Output: " + output)
|
|
100
|
-
|
|
101
|
-
asherah.shutdown()
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Environment Variables and AWS
|
|
105
|
-
|
|
106
|
-
If you're experiencing issues with AWS credentials, you can forcibly set the environment variables prior to calling setup in such a way as to ensure they're set for the Go runtime:
|
|
107
|
-
|
|
108
|
-
```javascript
|
|
22
|
+
## Quick start
|
|
109
23
|
|
|
24
|
+
```js
|
|
110
25
|
const asherah = require('asherah');
|
|
111
|
-
const fs = require('fs');
|
|
112
|
-
|
|
113
|
-
const config = {
|
|
114
|
-
KMS: 'aws',
|
|
115
|
-
Metastore: 'memory',
|
|
116
|
-
ServiceName: 'TestService',
|
|
117
|
-
ProductID: 'TestProduct',
|
|
118
|
-
Verbose: true,
|
|
119
|
-
EnableSessionCaching: true,
|
|
120
|
-
ExpireAfter: null,
|
|
121
|
-
CheckInterval: null,
|
|
122
|
-
ConnectionString: null,
|
|
123
|
-
ReplicaReadConsistency: null,
|
|
124
|
-
DynamoDBEndpoint: null,
|
|
125
|
-
DynamoDBRegion: null,
|
|
126
|
-
DynamoDBTableName: null,
|
|
127
|
-
SessionCacheMaxSize: null,
|
|
128
|
-
SessionCacheDuration: null,
|
|
129
|
-
RegionMap: {"us-west-2": "arn:aws:kms:us-west-2:XXXXXXXXX:key/XXXXXXXXXX"},
|
|
130
|
-
PreferredRegion: null,
|
|
131
|
-
EnableRegionSuffix: null,
|
|
132
|
-
DisableZeroCopy: null
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// Read the AWS environment variables from the JSON file
|
|
136
|
-
// DO NOT HARDCODE YOUR AWS CREDENTIALS
|
|
137
|
-
const awsEnvPath = './awsEnv.json';
|
|
138
|
-
const awsEnvData = fs.readFileSync(awsEnvPath, 'utf8');
|
|
139
|
-
const awsEnv = JSON.stringify(awsEnvData);
|
|
140
|
-
|
|
141
|
-
// Set the environment variables using the setenv function
|
|
142
|
-
asherah.setenv(awsEnv);
|
|
143
|
-
|
|
144
|
-
asherah.setup(config)
|
|
145
26
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const encrypted = asherah.encrypt('partition', data);
|
|
27
|
+
asherah.setup({
|
|
28
|
+
kms: 'static',
|
|
29
|
+
metastore: 'memory',
|
|
30
|
+
serviceName: 'myservice',
|
|
31
|
+
productId: 'myproduct',
|
|
32
|
+
});
|
|
153
33
|
|
|
34
|
+
const encrypted = asherah.encrypt('partition', Buffer.from('hello world'));
|
|
154
35
|
const decrypted = asherah.decrypt('partition', encrypted);
|
|
155
36
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
console.log("Output: " + output)
|
|
159
|
-
|
|
160
|
-
asherah.shutdown()
|
|
37
|
+
asherah.shutdown();
|
|
161
38
|
```
|
|
162
39
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
```json
|
|
166
|
-
{
|
|
167
|
-
"AXS_ACCESS_KEY_XD": "sample_access_key_xd",
|
|
168
|
-
"AXS_SXCRET_ACCXSS_KEY": "sample_sxcret_accxss_kxy",
|
|
169
|
-
"AXS_SXSSION_TXKEN": "sample_sxssion_txken"
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Go and Alpine / musl libc
|
|
174
|
-
|
|
175
|
-
The Golang compiler when creating shared libraries (.so) uses a Thread Local Storage model of init-exec. This model is inheriently incompatible with loading libraries at runtime with dlopen(), unless your libc reserves some space for dlopen()'ed libraries which is something of a hack. The most common libc, glibc does in fact reserve space for dlopen()'ed libraries that use init-exec model. The libc provided with Alpine is musl libc, and it does not participate in this hack / workaround of reserving space. Most compilers generate libraries with a Thread Local Storage model of global-dynamic which does not require this workaround, and the authors of musl libc do not feel that workaround should exist.
|
|
176
|
-
|
|
177
|
-
## Updating npm packages
|
|
40
|
+
## License
|
|
178
41
|
|
|
179
|
-
|
|
42
|
+
Licensed under the Apache License, Version 2.0.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
|
|
3
|
+
export type AsherahConfig = {
|
|
4
|
+
serviceName: string;
|
|
5
|
+
productId: string;
|
|
6
|
+
expireAfter?: number | null;
|
|
7
|
+
checkInterval?: number | null;
|
|
8
|
+
metastore: 'memory' | 'rdbms' | 'dynamodb';
|
|
9
|
+
connectionString?: string | null;
|
|
10
|
+
replicaReadConsistency?: string | null;
|
|
11
|
+
dynamoDBEndpoint?: string | null;
|
|
12
|
+
dynamoDBRegion?: string | null;
|
|
13
|
+
dynamoDBTableName?: string | null;
|
|
14
|
+
sessionCacheMaxSize?: number | null;
|
|
15
|
+
sessionCacheDuration?: number | null;
|
|
16
|
+
kms?: 'aws' | 'static' | null;
|
|
17
|
+
regionMap?: Record<string, string> | null;
|
|
18
|
+
preferredRegion?: string | null;
|
|
19
|
+
enableRegionSuffix?: boolean | null;
|
|
20
|
+
enableSessionCaching?: boolean | null;
|
|
21
|
+
verbose?: boolean | null;
|
|
22
|
+
sqlMetastoreDBType?: string | null;
|
|
23
|
+
disableZeroCopy?: boolean | null;
|
|
24
|
+
nullDataCheck?: boolean | null;
|
|
25
|
+
enableCanaries?: boolean | null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** Canonical godaddy/asherah-node PascalCase config format */
|
|
29
|
+
export type AsherahConfigCompat = {
|
|
30
|
+
readonly ServiceName: string;
|
|
31
|
+
readonly ProductID: string;
|
|
32
|
+
readonly ExpireAfter?: number | null;
|
|
33
|
+
readonly CheckInterval?: number | null;
|
|
34
|
+
readonly Metastore: 'memory' | 'rdbms' | 'dynamodb' | 'test-debug-memory';
|
|
35
|
+
readonly ConnectionString?: string | null;
|
|
36
|
+
readonly DynamoDBEndpoint?: string | null;
|
|
37
|
+
readonly DynamoDBRegion?: string | null;
|
|
38
|
+
readonly DynamoDBTableName?: string | null;
|
|
39
|
+
readonly SessionCacheMaxSize?: number | null;
|
|
40
|
+
readonly SessionCacheDuration?: number | null;
|
|
41
|
+
readonly KMS?: 'aws' | 'static' | 'test-debug-static' | null;
|
|
42
|
+
readonly RegionMap?: Record<string, string> | null;
|
|
43
|
+
readonly PreferredRegion?: string | null;
|
|
44
|
+
readonly EnableRegionSuffix?: boolean | null;
|
|
45
|
+
readonly EnableSessionCaching?: boolean | null;
|
|
46
|
+
readonly Verbose?: boolean | null;
|
|
47
|
+
readonly SQLMetastoreDBType?: string | null;
|
|
48
|
+
readonly ReplicaReadConsistency?: 'eventual' | 'global' | 'session' | null;
|
|
49
|
+
readonly DisableZeroCopy?: boolean | null;
|
|
50
|
+
readonly NullDataCheck?: boolean | null;
|
|
51
|
+
readonly EnableCanaries?: boolean | null;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Canonical godaddy/asherah-node log hook callback: (level: number, message: string) => void */
|
|
55
|
+
export type LogHookCallback = (level: number, message: string) => void;
|
|
56
|
+
|
|
57
|
+
export declare function setup(config: AsherahConfig | AsherahConfigCompat): void;
|
|
58
|
+
export declare function setupAsync(config: AsherahConfig | AsherahConfigCompat): Promise<void>;
|
|
59
|
+
export declare function shutdown(): void;
|
|
60
|
+
export declare function shutdownAsync(): Promise<void>;
|
|
61
|
+
export declare function getSetupStatus(): boolean;
|
|
62
|
+
export declare function setenv(env: string): void;
|
|
63
|
+
|
|
64
|
+
export declare function encrypt(partitionId: string, data: Buffer): string;
|
|
65
|
+
export declare function encryptAsync(partitionId: string, data: Buffer): Promise<string>;
|
|
66
|
+
export declare function decrypt(partitionId: string, dataRowRecordJson: string): Buffer;
|
|
67
|
+
export declare function decryptAsync(partitionId: string, dataRowRecordJson: string): Promise<Buffer>;
|
|
68
|
+
|
|
69
|
+
export declare function encryptString(partitionId: string, data: string): string;
|
|
70
|
+
export declare function encryptStringAsync(partitionId: string, data: string): Promise<string>;
|
|
71
|
+
export declare function decryptString(partitionId: string, dataRowRecordJson: string): string;
|
|
72
|
+
export declare function decryptStringAsync(partitionId: string, dataRowRecordJson: string): Promise<string>;
|
|
73
|
+
|
|
74
|
+
export declare function setMaxStackAllocItemSize(n: number): void;
|
|
75
|
+
export declare function setSafetyPaddingOverhead(n: number): void;
|
|
76
|
+
|
|
77
|
+
export type LogEvent = {
|
|
78
|
+
level: 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
79
|
+
message: string;
|
|
80
|
+
target: string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type MetricsEvent =
|
|
84
|
+
| { type: 'encrypt' | 'decrypt' | 'store' | 'load'; durationNs: number }
|
|
85
|
+
| { type: 'cache_hit' | 'cache_miss'; name: string };
|
|
86
|
+
|
|
87
|
+
export declare function setLogHook(hook: ((event: LogEvent) => void) | LogHookCallback | null): void;
|
|
88
|
+
export declare function setMetricsHook(hook: ((event: MetricsEvent) => void) | null): void;
|
|
89
|
+
|
|
90
|
+
// Canonical godaddy/asherah-node snake_case aliases
|
|
91
|
+
export declare function setup_async(config: AsherahConfig | AsherahConfigCompat): Promise<void>;
|
|
92
|
+
export declare function shutdown_async(): Promise<void>;
|
|
93
|
+
export declare function encrypt_async(partitionId: string, data: Buffer): Promise<string>;
|
|
94
|
+
export declare function encrypt_string(partitionId: string, data: string): string;
|
|
95
|
+
export declare function encrypt_string_async(partitionId: string, data: string): Promise<string>;
|
|
96
|
+
export declare function decrypt_async(partitionId: string, dataRowRecordJson: string): Promise<Buffer>;
|
|
97
|
+
export declare function decrypt_string(partitionId: string, dataRowRecordJson: string): string;
|
|
98
|
+
export declare function decrypt_string_async(partitionId: string, dataRowRecordJson: string): Promise<string>;
|
|
99
|
+
export declare function set_max_stack_alloc_item_size(n: number): void;
|
|
100
|
+
export declare function set_safety_padding_overhead(n: number): void;
|
|
101
|
+
export declare function set_log_hook(hook: ((event: LogEvent) => void) | LogHookCallback | null): void;
|
|
102
|
+
export declare function get_setup_status(): boolean;
|
package/npm/index.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
|
|
4
|
+
// Detect musl libc (Alpine Linux, etc.)
|
|
5
|
+
function isMusl() {
|
|
6
|
+
if (os.platform() !== 'linux') return false;
|
|
7
|
+
try {
|
|
8
|
+
// Node 18+: process.report.getReport() exposes glibc version
|
|
9
|
+
const report = process.report.getReport();
|
|
10
|
+
const header = typeof report === 'string' ? JSON.parse(report).header : report.header;
|
|
11
|
+
return !header.glibcVersionRuntime;
|
|
12
|
+
} catch {
|
|
13
|
+
// Fallback: check for musl dynamic linker
|
|
14
|
+
try {
|
|
15
|
+
return require('fs').readdirSync('/lib').some(f => f.startsWith('ld-musl-'));
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Determine current platform
|
|
23
|
+
function getPlatform() {
|
|
24
|
+
const type = os.platform();
|
|
25
|
+
const arch = os.arch();
|
|
26
|
+
|
|
27
|
+
if (type === 'darwin') {
|
|
28
|
+
if (arch === 'x64') return 'darwin-x64';
|
|
29
|
+
if (arch === 'arm64') return 'darwin-arm64';
|
|
30
|
+
}
|
|
31
|
+
if (type === 'linux') {
|
|
32
|
+
const libc = isMusl() ? 'musl' : 'gnu';
|
|
33
|
+
if (arch === 'x64') return `linux-x64-${libc}`;
|
|
34
|
+
if (arch === 'arm64') return `linux-arm64-${libc}`;
|
|
35
|
+
}
|
|
36
|
+
if (type === 'win32') {
|
|
37
|
+
if (arch === 'x64') return 'win32-x64-msvc';
|
|
38
|
+
if (arch === 'arm64') return 'win32-arm64-msvc';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
throw new Error(`Unsupported platform: ${type}-${arch}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const platform = getPlatform();
|
|
45
|
+
|
|
46
|
+
// Map platform to npm package name (win32 needed a different name to avoid npm spam filter)
|
|
47
|
+
const PLATFORM_PACKAGES = {
|
|
48
|
+
'darwin-arm64': 'asherah-darwin-arm64',
|
|
49
|
+
'darwin-x64': 'asherah-darwin-x64',
|
|
50
|
+
'linux-x64-gnu': 'asherah-linux-x64-gnu',
|
|
51
|
+
'linux-arm64-gnu': 'asherah-linux-arm64-gnu',
|
|
52
|
+
'linux-x64-musl': 'asherah-linux-x64-musl',
|
|
53
|
+
'linux-arm64-musl': 'asherah-linux-arm64-musl',
|
|
54
|
+
'win32-x64-msvc': 'asherah-windows-x64',
|
|
55
|
+
'win32-arm64-msvc': 'asherah-windows-arm64',
|
|
56
|
+
};
|
|
57
|
+
const packageName = PLATFORM_PACKAGES[platform] || `asherah-${platform}`;
|
|
58
|
+
|
|
59
|
+
// Try to load the native module:
|
|
60
|
+
// 1. Installed platform package (optionalDependency) — normal npm install
|
|
61
|
+
// 2. Bundled in platform subdirectory — development / CI builds
|
|
62
|
+
// 3. Legacy single-binary fallback
|
|
63
|
+
let native = null;
|
|
64
|
+
let lastErr = null;
|
|
65
|
+
|
|
66
|
+
const attempts = [
|
|
67
|
+
// Platform package installed as optionalDependency (e.g., asherah-darwin-arm64)
|
|
68
|
+
packageName,
|
|
69
|
+
// Bundled in platform subdirectory (development builds)
|
|
70
|
+
path.join(__dirname, platform, `index.${platform}.node`),
|
|
71
|
+
// Fallback to old single-binary locations
|
|
72
|
+
path.join(__dirname, 'asherah.node'),
|
|
73
|
+
path.join(__dirname, '..', 'index.node'),
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
for (const candidate of attempts) {
|
|
77
|
+
try {
|
|
78
|
+
native = require(candidate);
|
|
79
|
+
native.__binary = candidate;
|
|
80
|
+
break;
|
|
81
|
+
} catch (err) {
|
|
82
|
+
lastErr = err;
|
|
83
|
+
if (
|
|
84
|
+
err.code !== 'MODULE_NOT_FOUND' &&
|
|
85
|
+
err.code !== 'ERR_MODULE_NOT_FOUND' &&
|
|
86
|
+
err.code !== 'ERR_DLOPEN_FAILED'
|
|
87
|
+
) {
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!native) {
|
|
94
|
+
const detail = lastErr ? `: ${lastErr.message || String(lastErr)}` : '';
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Failed to load Asherah native addon for ${platform}. ` +
|
|
97
|
+
`Ensure the platform package '${packageName}' is installed${detail}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// --- Canonical godaddy/asherah-node compatibility layer ---
|
|
102
|
+
|
|
103
|
+
// PascalCase → camelCase config field mapping
|
|
104
|
+
const CONFIG_MAP = {
|
|
105
|
+
ServiceName: 'serviceName',
|
|
106
|
+
ProductID: 'productId',
|
|
107
|
+
ExpireAfter: 'expireAfter',
|
|
108
|
+
CheckInterval: 'checkInterval',
|
|
109
|
+
Metastore: 'metastore',
|
|
110
|
+
ConnectionString: 'connectionString',
|
|
111
|
+
DynamoDBEndpoint: 'dynamoDBEndpoint',
|
|
112
|
+
DynamoDBRegion: 'dynamoDBRegion',
|
|
113
|
+
DynamoDBTableName: 'dynamoDBTableName',
|
|
114
|
+
SessionCacheMaxSize: 'sessionCacheMaxSize',
|
|
115
|
+
SessionCacheDuration: 'sessionCacheDuration',
|
|
116
|
+
KMS: 'kms',
|
|
117
|
+
RegionMap: 'regionMap',
|
|
118
|
+
PreferredRegion: 'preferredRegion',
|
|
119
|
+
EnableRegionSuffix: 'enableRegionSuffix',
|
|
120
|
+
EnableSessionCaching: 'enableSessionCaching',
|
|
121
|
+
Verbose: 'verbose',
|
|
122
|
+
SQLMetastoreDBType: 'sqlMetastoreDBType',
|
|
123
|
+
ReplicaReadConsistency: 'replicaReadConsistency',
|
|
124
|
+
DisableZeroCopy: 'disableZeroCopy',
|
|
125
|
+
NullDataCheck: 'nullDataCheck',
|
|
126
|
+
EnableCanaries: 'enableCanaries',
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// Legacy/debug metastore aliases (match Go behavior)
|
|
130
|
+
const METASTORE_ALIASES = {
|
|
131
|
+
'test-debug-memory': 'memory',
|
|
132
|
+
'test-debug-sqlite': 'sqlite',
|
|
133
|
+
'test-debug-static': 'static',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Legacy/debug KMS aliases
|
|
137
|
+
const KMS_ALIASES = {
|
|
138
|
+
'test-debug-static': 'static',
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
function normalizeConfig(config) {
|
|
142
|
+
// Detect PascalCase format by checking for ServiceName (capital S)
|
|
143
|
+
if (!config || typeof config !== 'object' || !('ServiceName' in config)) {
|
|
144
|
+
return config;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const out = {};
|
|
148
|
+
for (const [key, value] of Object.entries(config)) {
|
|
149
|
+
const mapped = CONFIG_MAP[key];
|
|
150
|
+
if (mapped === undefined) {
|
|
151
|
+
// Unknown field — pass through as-is (may be a camelCase field mixed in)
|
|
152
|
+
out[key] = value;
|
|
153
|
+
} else if (mapped !== null) {
|
|
154
|
+
out[mapped] = value;
|
|
155
|
+
}
|
|
156
|
+
// mapped === null means ignored (Go-specific)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Normalize metastore aliases
|
|
160
|
+
if (typeof out.metastore === 'string') {
|
|
161
|
+
const lower = out.metastore.toLowerCase();
|
|
162
|
+
out.metastore = METASTORE_ALIASES[lower] || lower;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Normalize KMS aliases
|
|
166
|
+
if (typeof out.kms === 'string') {
|
|
167
|
+
const lower = out.kms.toLowerCase();
|
|
168
|
+
out.kms = KMS_ALIASES[lower] || lower;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Log level mapping: Rust level string → zerolog numeric (used by Go asherah)
|
|
175
|
+
const LEVEL_TO_NUMBER = {
|
|
176
|
+
trace: -1,
|
|
177
|
+
debug: 0,
|
|
178
|
+
info: 1,
|
|
179
|
+
warn: 2,
|
|
180
|
+
error: 3,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Wrap setup to normalize config
|
|
184
|
+
function setup(config) {
|
|
185
|
+
return native.setup(normalizeConfig(config));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function setupAsync(config) {
|
|
189
|
+
return native.setupAsync(normalizeConfig(config));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// set_log_hook: accept canonical (level, message) callback or native (event) callback
|
|
193
|
+
function set_log_hook(callback) {
|
|
194
|
+
if (callback == null) {
|
|
195
|
+
return native.setLogHook(null);
|
|
196
|
+
}
|
|
197
|
+
// Canonical callback: (level: number, message: string) => void (arity 2)
|
|
198
|
+
// Native callback: (event: {level, message, target}) => void (arity 1)
|
|
199
|
+
if (callback.length >= 2) {
|
|
200
|
+
return native.setLogHook(function (event) {
|
|
201
|
+
const numLevel =
|
|
202
|
+
LEVEL_TO_NUMBER[event.level] !== undefined
|
|
203
|
+
? LEVEL_TO_NUMBER[event.level]
|
|
204
|
+
: 1;
|
|
205
|
+
callback(numLevel, event.message);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return native.setLogHook(callback);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Export everything from native addon
|
|
212
|
+
Object.assign(module.exports, native);
|
|
213
|
+
|
|
214
|
+
// Override setup/setupAsync with normalizing versions
|
|
215
|
+
module.exports.setup = setup;
|
|
216
|
+
module.exports.setupAsync = setupAsync;
|
|
217
|
+
|
|
218
|
+
// snake_case aliases for canonical API compatibility
|
|
219
|
+
module.exports.setup_async = setupAsync;
|
|
220
|
+
module.exports.shutdown_async = native.shutdownAsync;
|
|
221
|
+
module.exports.encrypt_async = native.encryptAsync;
|
|
222
|
+
module.exports.encrypt_string = native.encryptString;
|
|
223
|
+
module.exports.encrypt_string_async = native.encryptStringAsync;
|
|
224
|
+
module.exports.decrypt_async = native.decryptAsync;
|
|
225
|
+
module.exports.decrypt_string = native.decryptString;
|
|
226
|
+
module.exports.decrypt_string_async = native.decryptStringAsync;
|
|
227
|
+
module.exports.set_max_stack_alloc_item_size = native.setMaxStackAllocItemSize;
|
|
228
|
+
module.exports.set_safety_padding_overhead = native.setSafetyPaddingOverhead;
|
|
229
|
+
module.exports.set_log_hook = set_log_hook;
|
|
230
|
+
module.exports.get_setup_status = native.getSetupStatus;
|
package/package.json
CHANGED
|
@@ -1,87 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asherah",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-beta.10",
|
|
4
|
+
"private": false,
|
|
4
5
|
"description": "Asherah envelope encryption and key rotation library",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
7
|
-
"
|
|
8
|
-
"."
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
"main": "npm/index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"npm/index.js",
|
|
10
|
+
"index.d.ts",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"napi": {
|
|
15
|
+
"binaryName": "index",
|
|
16
|
+
"targets": [
|
|
17
|
+
"x86_64-apple-darwin",
|
|
18
|
+
"aarch64-apple-darwin",
|
|
19
|
+
"x86_64-unknown-linux-gnu",
|
|
20
|
+
"aarch64-unknown-linux-gnu",
|
|
21
|
+
"x86_64-unknown-linux-musl",
|
|
22
|
+
"aarch64-unknown-linux-musl",
|
|
23
|
+
"x86_64-pc-windows-msvc",
|
|
24
|
+
"aarch64-pc-windows-msvc"
|
|
25
|
+
]
|
|
18
26
|
},
|
|
19
27
|
"scripts": {
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"test:
|
|
24
|
-
"test:mocha": "mocha",
|
|
25
|
-
"test": "nyc npm run test:mocha",
|
|
26
|
-
"test:bun": "bun test/bun-test.js",
|
|
27
|
-
"debug": "nyc npm run test:mocha-debug",
|
|
28
|
-
"posttest": "npm run lint && npm run test:bun",
|
|
29
|
-
"lint": "eslint src/**.ts --fix",
|
|
30
|
-
"update": "npx npm-check-updates --target latest -u -x mocha && npm i && npm audit fix"
|
|
28
|
+
"build": "napi build",
|
|
29
|
+
"build:release": "napi build --release",
|
|
30
|
+
"test": "node test/roundtrip.js",
|
|
31
|
+
"test:bun": "bun test/roundtrip.js"
|
|
31
32
|
},
|
|
32
|
-
"keywords": [],
|
|
33
|
-
"author": "Jeremiah Gowdy <jeremiah@gowdy.me>",
|
|
34
|
-
"license": "MIT",
|
|
35
|
-
"files": [
|
|
36
|
-
"binding.gyp",
|
|
37
|
-
"src/asherah_async_worker.h",
|
|
38
|
-
"src/asherah.cc",
|
|
39
|
-
"src/cobhan_buffer_napi.h",
|
|
40
|
-
"src/cobhan_buffer.h",
|
|
41
|
-
"src/hints.h",
|
|
42
|
-
"src/logging.h",
|
|
43
|
-
"src/logging_napi.cc",
|
|
44
|
-
"src/logging_napi.h",
|
|
45
|
-
"src/logging_stderr.cc",
|
|
46
|
-
"src/logging_stderr.h",
|
|
47
|
-
"src/napi_utils.h",
|
|
48
|
-
"src/scoped_allocate.h",
|
|
49
|
-
"src/asherah.d.ts",
|
|
50
|
-
"scripts/download-libraries.sh",
|
|
51
|
-
"scripts/build.sh",
|
|
52
|
-
"SHA256SUMS",
|
|
53
|
-
"SHA256SUMS-darwin",
|
|
54
|
-
".asherah-version"
|
|
55
|
-
],
|
|
56
33
|
"devDependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"@eslint/eslintrc": "^3.2.0",
|
|
59
|
-
"@eslint/js": "^9.20.0",
|
|
60
|
-
"@types/chai": "^5.0.1",
|
|
61
|
-
"@types/mocha": "^10.0.10",
|
|
62
|
-
"@types/node": "^22.13.1",
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "^8.24.0",
|
|
64
|
-
"@typescript-eslint/parser": "^8.24.0",
|
|
65
|
-
"chai": "^5.1.2",
|
|
66
|
-
"eslint": "^9.20.1",
|
|
67
|
-
"globals": "^15.15.0",
|
|
68
|
-
"microtime": "^3.1.1",
|
|
69
|
-
"mocha": "^10.0.0",
|
|
70
|
-
"node-api-headers": "^1.5.0",
|
|
71
|
-
"nyc": "^17.1.0",
|
|
72
|
-
"tsx": "^4.21.0",
|
|
73
|
-
"typescript": "^5.7.3",
|
|
74
|
-
"winston": "^3.17.0"
|
|
34
|
+
"@napi-rs/cli": "^2.18.0"
|
|
75
35
|
},
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"ts"
|
|
79
|
-
],
|
|
80
|
-
"recursive": true,
|
|
81
|
-
"spec": "test/**/*.spec.ts",
|
|
82
|
-
"require": "tsx"
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">= 18"
|
|
83
38
|
},
|
|
84
|
-
"
|
|
85
|
-
"
|
|
39
|
+
"optionalDependencies": {
|
|
40
|
+
"asherah-darwin-arm64": "4.0.0-beta.10",
|
|
41
|
+
"asherah-darwin-x64": "4.0.0-beta.10",
|
|
42
|
+
"asherah-linux-x64-gnu": "4.0.0-beta.10",
|
|
43
|
+
"asherah-linux-arm64-gnu": "4.0.0-beta.10",
|
|
44
|
+
"asherah-linux-x64-musl": "4.0.0-beta.10",
|
|
45
|
+
"asherah-linux-arm64-musl": "4.0.0-beta.10",
|
|
46
|
+
"asherah-windows-x64": "4.0.0-beta.10",
|
|
47
|
+
"asherah-windows-arm64": "4.0.0-beta.10"
|
|
86
48
|
}
|
|
87
49
|
}
|
package/.asherah-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ASHERAH_VERSION=v0.5.0
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
The MIT License (MIT)
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 GoDaddy Operating Company, LLC.
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|