mirror of
https://github.com/Keeper-Security/harness-integration.git
synced 2026-06-04 10:14:56 +08:00
harness CI drone plugin PLUGIN_KSM_CONFIG convention added, multi-platform Docker (amd64/arm64) support and added MIT license
This commit is contained in:
@@ -101,10 +101,11 @@ jobs:
|
|||||||
echo "Image tag: ${IMAGE_TAG}"
|
echo "Image tag: ${IMAGE_TAG}"
|
||||||
echo "Latest tag: ${LATEST_TAG}"
|
echo "Latest tag: ${LATEST_TAG}"
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image (multi-platform)
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
push: ${{ github.event_name != 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/') }}
|
push: ${{ github.event_name != 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/') }}
|
||||||
tags: |
|
tags: |
|
||||||
${{ steps.docker_tags.outputs.IMAGE_TAG }}
|
${{ steps.docker_tags.outputs.IMAGE_TAG }}
|
||||||
@@ -281,11 +282,10 @@ jobs:
|
|||||||
spec:
|
spec:
|
||||||
image: ${{ steps.docker_image.outputs.IMAGE_NAME }}
|
image: ${{ steps.docker_image.outputs.IMAGE_NAME }}
|
||||||
settings:
|
settings:
|
||||||
|
ksm_config: <+secrets.getValue("Keeper_Config_Secret")>
|
||||||
secrets: |
|
secrets: |
|
||||||
VeYTRo-PHElAwfQT6f0TIA/field/password > DB_PASSWORD
|
VeYTRo-PHElAwfQT6f0TIA/field/password > DB_PASSWORD
|
||||||
VeYTRo-PHElAwfQT6f0TIA/field/login > DB_USERNAME
|
VeYTRo-PHElAwfQT6f0TIA/field/login > DB_USERNAME
|
||||||
envVariables:
|
|
||||||
KSM_CONFIG: <+secrets.getValue("Keeper_Config_Secret")>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### What's Changed
|
### What's Changed
|
||||||
@@ -293,4 +293,4 @@ jobs:
|
|||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -59,13 +59,12 @@ pipeline:
|
|||||||
name: Fetch_Keeper_Secrets
|
name: Fetch_Keeper_Secrets
|
||||||
identifier: Fetch_Keeper_Secrets
|
identifier: Fetch_Keeper_Secrets
|
||||||
spec:
|
spec:
|
||||||
image: dhborse/keeper-harness-plugin
|
image: keeper/harness-plugin:latest
|
||||||
settings:
|
settings:
|
||||||
|
ksm_config: <+secrets.getValue("keeper_base64_secret")>
|
||||||
secrets: |
|
secrets: |
|
||||||
RECORD_UID/field/password > PASSWORD
|
RECORD_UID/field/password > PASSWORD
|
||||||
RECORD_UID/field/login > USERNAME
|
RECORD_UID/field/login > USERNAME
|
||||||
envVariables:
|
|
||||||
KSM_CONFIG: <+secrets.getValue("keeper_base64_secret")>
|
|
||||||
- step:
|
- step:
|
||||||
type: Run
|
type: Run
|
||||||
name: Use_Secrets
|
name: Use_Secrets
|
||||||
@@ -87,13 +86,15 @@ pipeline:
|
|||||||
|
|
||||||
## Inputs
|
## Inputs
|
||||||
|
|
||||||
### KSM_CONFIG
|
### ksm_config (PLUGIN_KSM_CONFIG)
|
||||||
|
|
||||||
Keeper Secrets Manager configuration for authentication. Store in Harness secrets and reference:
|
Keeper Secrets Manager configuration for authentication. Store in Harness secrets and reference via the standard `settings` block (Harness/Drone maps `ksm_config` to `PLUGIN_KSM_CONFIG`):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
envVariables:
|
settings:
|
||||||
KSM_CONFIG: <+secrets.getValue("Keeper_Config_Secret")>
|
ksm_config: <+secrets.getValue("Keeper_Config_Secret")>
|
||||||
|
secrets: |
|
||||||
|
RECORD_UID/field/password > PASSWORD
|
||||||
```
|
```
|
||||||
|
|
||||||
**Supported Formats:**
|
**Supported Formats:**
|
||||||
@@ -172,7 +173,7 @@ Secrets are stored in `/harness/secrets/` directory. Read them in subsequent ste
|
|||||||
- **Scope:** Pipeline execution only - automatically cleaned up after completion
|
- **Scope:** Pipeline execution only - automatically cleaned up after completion
|
||||||
- **Access:** Read files directly using `cat` or file operations
|
- **Access:** Read files directly using `cat` or file operations
|
||||||
|
|
||||||
The `envVariables` section is **only** used to pass `KSM_CONFIG` to the plugin. Actual secrets are written to files in `/harness/secrets/` directory.
|
The `ksm_config` setting is passed via the standard `settings` block (mapped to `PLUGIN_KSM_CONFIG`). Actual secrets are written to files in `/harness/secrets/` directory.
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
@@ -194,7 +195,7 @@ The `envVariables` section is **only** used to pass `KSM_CONFIG` to the plugin.
|
|||||||
|
|
||||||
| Error | Solution |
|
| Error | Solution |
|
||||||
|-------|----------|
|
|-------|----------|
|
||||||
| `KSM config is required` | Verify secret exists and expression `<+secrets.getValue("SECRET_NAME")>` is correct |
|
| `KSM config is required` | Verify secret exists, `ksm_config` is set in settings, and expression `<+secrets.getValue("SECRET_NAME")>` is correct |
|
||||||
| `Invalid token format` | Check token starts with `US:` or `{` for JSON config |
|
| `Invalid token format` | Check token starts with `US:` or `{` for JSON config |
|
||||||
| `Value not found for notation` | Verify Record UID, field name (case-sensitive), and Application permissions |
|
| `Value not found for notation` | Verify Record UID, field name (case-sensitive), and Application permissions |
|
||||||
| `Failed to download file` | Check file exists in record, name matches exactly, and Application has file access permissions |
|
| `Failed to download file` | Check file exists in record, name matches exactly, and Application has file access permissions |
|
||||||
|
|||||||
+3
-3
@@ -2,7 +2,7 @@
|
|||||||
"name": "harness_keeper_plugin",
|
"name": "harness_keeper_plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "",
|
"description": "Keeper Secrets Manager integration for Harness CI",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --coverage",
|
"test": "jest --coverage",
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
"lint:fix": "eslint . --fix"
|
"lint:fix": "eslint . --fix"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "Keeper Security",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keeper-security/secrets-manager-core": "^17.4.0"
|
"@keeper-security/secrets-manager-core": "^17.4.0"
|
||||||
|
|||||||
+2
-2
@@ -29,7 +29,7 @@ const splitInput = (text) => {
|
|||||||
const processToken = (rawToken) => {
|
const processToken = (rawToken) => {
|
||||||
if (!rawToken) {
|
if (!rawToken) {
|
||||||
core.error('KSM config is required');
|
core.error('KSM config is required');
|
||||||
core.error('Set KSM_CONFIG environment variable');
|
core.error('Set PLUGIN_KSM_CONFIG (or ksm_config in settings)');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ const runPlugin = async () => {
|
|||||||
core.info('Starting Keeper Secrets Manager plugin');
|
core.info('Starting Keeper Secrets Manager plugin');
|
||||||
fs.mkdirSync('/app', { recursive: true });
|
fs.mkdirSync('/app', { recursive: true });
|
||||||
|
|
||||||
const { token, isConfigJson, config } = processToken(process.env.KSM_CONFIG);
|
const { token, isConfigJson, config } = processToken(process.env.PLUGIN_KSM_CONFIG);
|
||||||
const inputs = parseSecretMappings();
|
const inputs = parseSecretMappings();
|
||||||
const storage = await setupStorage(token, isConfigJson, config);
|
const storage = await setupStorage(token, isConfigJson, config);
|
||||||
const secrets = await getSecrets({ storage });
|
const secrets = await getSecrets({ storage });
|
||||||
|
|||||||
+65
-65
@@ -72,7 +72,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
pathModule.join = path.join;
|
pathModule.join = path.join;
|
||||||
|
|
||||||
// Clear environment variables
|
// Clear environment variables
|
||||||
delete process.env.KSM_CONFIG;
|
delete process.env.PLUGIN_KSM_CONFIG;
|
||||||
delete process.env.PLUGIN_SECRETS;
|
delete process.env.PLUGIN_SECRETS;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -89,45 +89,45 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('processToken - Error Cases', () => {
|
describe('processToken - Error Cases', () => {
|
||||||
test('should exit when rawToken is null', () => {
|
test('should exit when rawToken is null', () => {
|
||||||
delete process.env.KSM_CONFIG;
|
delete process.env.PLUGIN_KSM_CONFIG;
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('KSM config is required'));
|
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('KSM config is required'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when rawToken is undefined', () => {
|
test('should exit when rawToken is undefined', () => {
|
||||||
delete process.env.KSM_CONFIG;
|
delete process.env.PLUGIN_KSM_CONFIG;
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when rawToken is empty string', () => {
|
test('should exit when rawToken is empty string', () => {
|
||||||
process.env.KSM_CONFIG = '';
|
process.env.PLUGIN_KSM_CONFIG = '';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when token contains ${ Harness expression', () => {
|
test('should exit when token contains ${ Harness expression', () => {
|
||||||
process.env.KSM_CONFIG = '${harness.expression}';
|
process.env.PLUGIN_KSM_CONFIG = '${harness.expression}';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Harness expression not resolved'));
|
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Harness expression not resolved'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when token contains <+ Harness expression', () => {
|
test('should exit when token contains <+ Harness expression', () => {
|
||||||
process.env.KSM_CONFIG = '<+expression>';
|
process.env.PLUGIN_KSM_CONFIG = '<+expression>';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when token contains ngSecretManager', () => {
|
test('should exit when token contains ngSecretManager', () => {
|
||||||
process.env.KSM_CONFIG = 'ngSecretManager.token';
|
process.env.PLUGIN_KSM_CONFIG = 'ngSecretManager.token';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when token is empty after trim', () => {
|
test('should exit when token is empty after trim', () => {
|
||||||
process.env.KSM_CONFIG = ' ';
|
process.env.PLUGIN_KSM_CONFIG = ' ';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Token is null or empty'));
|
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Token is null or empty'));
|
||||||
@@ -135,7 +135,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
test('should exit when JSON config is missing hostname field', () => {
|
test('should exit when JSON config is missing hostname field', () => {
|
||||||
const jsonConfig = JSON.stringify({ clientId: 'client', privateKey: 'key' });
|
const jsonConfig = JSON.stringify({ clientId: 'client', privateKey: 'key' });
|
||||||
process.env.KSM_CONFIG = jsonConfig;
|
process.env.PLUGIN_KSM_CONFIG = jsonConfig;
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Missing required fields'));
|
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Missing required fields'));
|
||||||
@@ -143,34 +143,34 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
test('should exit when JSON config is missing clientId field', () => {
|
test('should exit when JSON config is missing clientId field', () => {
|
||||||
const jsonConfig = JSON.stringify({ hostname: 'test.com', privateKey: 'key' });
|
const jsonConfig = JSON.stringify({ hostname: 'test.com', privateKey: 'key' });
|
||||||
process.env.KSM_CONFIG = jsonConfig;
|
process.env.PLUGIN_KSM_CONFIG = jsonConfig;
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when JSON config is missing privateKey field', () => {
|
test('should exit when JSON config is missing privateKey field', () => {
|
||||||
const jsonConfig = JSON.stringify({ hostname: 'test.com', clientId: 'client' });
|
const jsonConfig = JSON.stringify({ hostname: 'test.com', clientId: 'client' });
|
||||||
process.env.KSM_CONFIG = jsonConfig;
|
process.env.PLUGIN_KSM_CONFIG = jsonConfig;
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when JSON config is missing multiple fields', () => {
|
test('should exit when JSON config is missing multiple fields', () => {
|
||||||
const jsonConfig = JSON.stringify({ hostname: 'test.com' });
|
const jsonConfig = JSON.stringify({ hostname: 'test.com' });
|
||||||
process.env.KSM_CONFIG = jsonConfig;
|
process.env.PLUGIN_KSM_CONFIG = jsonConfig;
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when JSON config is invalid', () => {
|
test('should exit when JSON config is invalid', () => {
|
||||||
process.env.KSM_CONFIG = '{invalid json}';
|
process.env.PLUGIN_KSM_CONFIG = '{invalid json}';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Invalid JSON config'));
|
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Invalid JSON config'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should exit when token format is invalid (not US: or JSON)', () => {
|
test('should exit when token format is invalid (not US: or JSON)', () => {
|
||||||
process.env.KSM_CONFIG = 'INVALID:token';
|
process.env.PLUGIN_KSM_CONFIG = 'INVALID:token';
|
||||||
require('../index');
|
require('../index');
|
||||||
expect(mockExit).toHaveBeenCalledWith(1);
|
expect(mockExit).toHaveBeenCalledWith(1);
|
||||||
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Invalid token format'));
|
expect(mockStderrWrite).toHaveBeenCalledWith(expect.stringContaining('Invalid token format'));
|
||||||
@@ -180,7 +180,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
describe('processToken - Success Cases', () => {
|
describe('processToken - Success Cases', () => {
|
||||||
test('should decode base64 token successfully', async () => {
|
test('should decode base64 token successfully', async () => {
|
||||||
const base64Token = Buffer.from('US:decoded-token').toString('base64');
|
const base64Token = Buffer.from('US:decoded-token').toString('base64');
|
||||||
process.env.KSM_CONFIG = base64Token;
|
process.env.PLUGIN_KSM_CONFIG = base64Token;
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -193,7 +193,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle base64 decode error gracefully', async () => {
|
test('should handle base64 decode error gracefully', async () => {
|
||||||
process.env.KSM_CONFIG = 'invalid-base64!@#';
|
process.env.PLUGIN_KSM_CONFIG = 'invalid-base64!@#';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -207,7 +207,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
test('should parse valid JSON config', async () => {
|
test('should parse valid JSON config', async () => {
|
||||||
const jsonConfig = JSON.stringify({ hostname: 'test.com', clientId: 'client', privateKey: 'key' });
|
const jsonConfig = JSON.stringify({ hostname: 'test.com', clientId: 'client', privateKey: 'key' });
|
||||||
process.env.KSM_CONFIG = jsonConfig;
|
process.env.PLUGIN_KSM_CONFIG = jsonConfig;
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
const mockStorage = {};
|
const mockStorage = {};
|
||||||
localConfigStorage.mockReturnValue(mockStorage);
|
localConfigStorage.mockReturnValue(mockStorage);
|
||||||
@@ -221,7 +221,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should accept US: token format', async () => {
|
test('should accept US: token format', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test-token';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test-token';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
const mockStorage = {};
|
const mockStorage = {};
|
||||||
localConfigStorage.mockReturnValue(mockStorage);
|
localConfigStorage.mockReturnValue(mockStorage);
|
||||||
@@ -235,7 +235,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle token with whitespace', async () => {
|
test('should handle token with whitespace', async () => {
|
||||||
process.env.KSM_CONFIG = ' US:test-token ';
|
process.env.PLUGIN_KSM_CONFIG = ' US:test-token ';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -248,7 +248,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should call info function on plugin start', async () => {
|
test('should call info function on plugin start', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -268,7 +268,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
throw new Error('Base64 decode error');
|
throw new Error('Base64 decode error');
|
||||||
});
|
});
|
||||||
|
|
||||||
process.env.KSM_CONFIG = 'not-us-format-token';
|
process.env.PLUGIN_KSM_CONFIG = 'not-us-format-token';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -284,7 +284,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('parseSecretMappings', () => {
|
describe('parseSecretMappings', () => {
|
||||||
test('should treat env: prefix as literal destination name (no special parsing)', async () => {
|
test('should treat env: prefix as literal destination name (no special parsing)', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -297,7 +297,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should parse file: destination type', async () => {
|
test('should parse file: destination type', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -310,7 +310,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should parse output destination type (default)', async () => {
|
test('should parse output destination type (default)', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -323,7 +323,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle input without > separator', async () => {
|
test('should handle input without > separator', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation';
|
process.env.PLUGIN_SECRETS = 'notation';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -336,7 +336,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle multiple > characters', async () => {
|
test('should handle multiple > characters', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>part1>destination';
|
process.env.PLUGIN_SECRETS = 'notation>part1>destination';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -348,7 +348,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle multiple secret mappings', async () => {
|
test('should handle multiple secret mappings', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation1>env:VAR1\nnotation2>file:/path/file\nnotation3>output1';
|
process.env.PLUGIN_SECRETS = 'notation1>env:VAR1\nnotation2>file:/path/file\nnotation3>output1';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -361,7 +361,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should filter empty lines from multiline input', async () => {
|
test('should filter empty lines from multiline input', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation1>output1\n\nnotation2>output2\n \nnotation3>output3';
|
process.env.PLUGIN_SECRETS = 'notation1>output1\n\nnotation2>output2\n \nnotation3>output3';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -374,7 +374,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle empty secrets input', async () => {
|
test('should handle empty secrets input', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = '';
|
process.env.PLUGIN_SECRETS = '';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -388,7 +388,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('runPlugin - File Handling', () => {
|
describe('runPlugin - File Handling', () => {
|
||||||
test('should create /app directory', async () => {
|
test('should create /app directory', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
const mockStorage = {};
|
const mockStorage = {};
|
||||||
localConfigStorage.mockReturnValue(mockStorage);
|
localConfigStorage.mockReturnValue(mockStorage);
|
||||||
@@ -406,7 +406,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should treat file: prefix as literal destination (writes to /harness/secrets/)', async () => {
|
test('should treat file: prefix as literal destination (writes to /harness/secrets/)', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -419,7 +419,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should create /harness/secrets for any destination', async () => {
|
test('should create /harness/secrets for any destination', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -433,7 +433,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file secret with fileId', async () => {
|
test('should handle file secret with fileId', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -448,7 +448,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file secret with fileUid', async () => {
|
test('should handle file secret with fileUid', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -463,7 +463,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file secret with url', async () => {
|
test('should handle file secret with url', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -478,7 +478,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file secret with /file/ notation', async () => {
|
test('should handle file secret with /file/ notation', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'record/field/file/file.txt>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'record/field/file/file.txt>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -495,7 +495,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle downloadFile error gracefully', async () => {
|
test('should handle downloadFile error gracefully', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -510,7 +510,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle Uint8Array file data', async () => {
|
test('should handle Uint8Array file data', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -526,7 +526,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle Buffer file data', async () => {
|
test('should handle Buffer file data', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -541,7 +541,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle other file data types', async () => {
|
test('should handle other file data types', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -557,7 +557,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file data that is neither Uint8Array nor Buffer (line 135 branch)', async () => {
|
test('should handle file data that is neither Uint8Array nor Buffer (line 135 branch)', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -576,7 +576,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file data that is Buffer (line 134 branch)', async () => {
|
test('should handle file data that is Buffer (line 134 branch)', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -598,7 +598,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
test('should handle file data that is plain Uint8Array (not Buffer)', async () => {
|
test('should handle file data that is plain Uint8Array (not Buffer)', async () => {
|
||||||
// Test the second branch: Buffer.isBuffer is false but instanceof Uint8Array is true
|
// Test the second branch: Buffer.isBuffer is false but instanceof Uint8Array is true
|
||||||
// Use a plain Uint8Array (not a Buffer) to test the middle branch of the ternary
|
// Use a plain Uint8Array (not a Buffer) to test the middle branch of the ternary
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
process.env.PLUGIN_SECRETS = 'notation>file:/path/to/file.txt';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -624,7 +624,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('runPlugin - Secret Value Handling', () => {
|
describe('runPlugin - Secret Value Handling', () => {
|
||||||
test('should handle string secret value', async () => {
|
test('should handle string secret value', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -637,7 +637,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle Buffer secret value', async () => {
|
test('should handle Buffer secret value', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -650,7 +650,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle non-string, non-buffer secret value', async () => {
|
test('should handle non-string, non-buffer secret value', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -663,7 +663,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should skip secret when value is not found', async () => {
|
test('should skip secret when value is not found', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -677,7 +677,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should skip secret when value is undefined', async () => {
|
test('should skip secret when value is undefined', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -692,7 +692,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('runPlugin - Destination Types', () => {
|
describe('runPlugin - Destination Types', () => {
|
||||||
test('should handle env-prefixed destination as literal (writes to /harness/secrets/)', async () => {
|
test('should handle env-prefixed destination as literal (writes to /harness/secrets/)', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -707,7 +707,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle env-prefixed destination with Buffer data', async () => {
|
test('should handle env-prefixed destination with Buffer data', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -722,7 +722,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle env-prefixed destination with non-Buffer data', async () => {
|
test('should handle env-prefixed destination with non-Buffer data', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
process.env.PLUGIN_SECRETS = 'notation>env:VAR_NAME';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -738,7 +738,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
|
|
||||||
test('should create /harness/secrets directory for non-file destinations', async () => {
|
test('should create /harness/secrets directory for non-file destinations', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -751,7 +751,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should set file permissions to 0o600 for secret files', async () => {
|
test('should set file permissions to 0o600 for secret files', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -764,7 +764,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should write only to /harness/secrets for output destinations', async () => {
|
test('should write only to /harness/secrets for output destinations', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
process.env.PLUGIN_SECRETS = 'notation>output_var';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -779,7 +779,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('runPlugin - Error Handling', () => {
|
describe('runPlugin - Error Handling', () => {
|
||||||
test('should handle storage initialization error', async () => {
|
test('should handle storage initialization error', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockRejectedValue(new Error('Storage initialization failed'));
|
initializeStorage.mockRejectedValue(new Error('Storage initialization failed'));
|
||||||
@@ -791,7 +791,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle token-related error with specific message', async () => {
|
test('should handle token-related error with specific message', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockRejectedValue(new Error('Invalid token'));
|
initializeStorage.mockRejectedValue(new Error('Invalid token'));
|
||||||
@@ -802,7 +802,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle expired token error', async () => {
|
test('should handle expired token error', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockRejectedValue(new Error('Token expired'));
|
initializeStorage.mockRejectedValue(new Error('Token expired'));
|
||||||
@@ -813,7 +813,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle invalid token error', async () => {
|
test('should handle invalid token error', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockRejectedValue(new Error('invalid'));
|
initializeStorage.mockRejectedValue(new Error('invalid'));
|
||||||
@@ -824,7 +824,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle getSecrets error', async () => {
|
test('should handle getSecrets error', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -837,7 +837,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle generic error without token message', async () => {
|
test('should handle generic error without token message', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -852,7 +852,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
|
|
||||||
describe('Edge Cases and Integration', () => {
|
describe('Edge Cases and Integration', () => {
|
||||||
test('should handle null secret object', async () => {
|
test('should handle null secret object', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -865,7 +865,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle object secret without file properties', async () => {
|
test('should handle object secret without file properties', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation>output';
|
process.env.PLUGIN_SECRETS = 'notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -880,7 +880,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
test('should handle object secret without file properties and notation without /file/', async () => {
|
test('should handle object secret without file properties and notation without /file/', async () => {
|
||||||
// Test the branch where typeof secret === 'object' && secret !== null is true
|
// Test the branch where typeof secret === 'object' && secret !== null is true
|
||||||
// but (secret.fileId || secret.fileUid || secret.url || notationIsFile) is false
|
// but (secret.fileId || secret.fileUid || secret.url || notationIsFile) is false
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'regular/notation>output';
|
process.env.PLUGIN_SECRETS = 'regular/notation>output';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -896,7 +896,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle complex multiline input with mixed types', async () => {
|
test('should handle complex multiline input with mixed types', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'notation1>env:VAR1\nnotation2>file:/path/file\nnotation3>output1\nnotation4>env:VAR2';
|
process.env.PLUGIN_SECRETS = 'notation1>env:VAR1\nnotation2>file:/path/file\nnotation3>output1\nnotation4>env:VAR2';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
@@ -909,7 +909,7 @@ describe('index.js - Complete Test Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should handle file notation with multiple file references', async () => {
|
test('should handle file notation with multiple file references', async () => {
|
||||||
process.env.KSM_CONFIG = 'US:test';
|
process.env.PLUGIN_KSM_CONFIG = 'US:test';
|
||||||
process.env.PLUGIN_SECRETS = 'record1/field/file/file1.txt>file:/path/file1\nrecord2/field/file/file2.txt>file:/path/file2';
|
process.env.PLUGIN_SECRETS = 'record1/field/file/file1.txt>file:/path/file1\nrecord2/field/file/file2.txt>file:/path/file2';
|
||||||
localConfigStorage.mockReturnValue({});
|
localConfigStorage.mockReturnValue({});
|
||||||
initializeStorage.mockResolvedValue();
|
initializeStorage.mockResolvedValue();
|
||||||
|
|||||||
Reference in New Issue
Block a user