test: add tests for DNS API Keys in OpenBao

This commit is contained in:
2026-08-02 00:34:56 -04:00
parent b50a1de76f
commit 9029de825c
2 changed files with 72 additions and 3 deletions
+5 -3
View File
@@ -153,7 +153,7 @@ class DnsProvider extends Table{
let provider = new __intraModel.Provider(data, ...args); let provider = new __intraModel.Provider(data, ...args);
let domains = await provider.listDomains(); let domains = await provider.listDomains();
for (let key in secrets) delete data[key]; for (let key in secrets) data[key] = '********';
let instance = await super.create.call(__intraModel, data, ...args); let instance = await super.create.call(__intraModel, data, ...args);
@@ -240,9 +240,11 @@ class DnsProvider extends Table{
let secrets = {}; let secrets = {};
if (Provider) { if (Provider) {
for (let key in Provider._keyMap) { for (let key in Provider._keyMap) {
if (Provider._keyMap[key].isPrivate && data[key] !== undefined) { if (Provider._keyMap[key].isPrivate && data[key] !== undefined && data[key] !== '********') {
secrets[key] = data[key]; secrets[key] = data[key];
delete data[key]; data[key] = '********';
} else if (Provider._keyMap[key].isPrivate && data[key] === '********') {
delete data[key]; // Do not update the masked value if it's sent back
} }
} }
} }
@@ -0,0 +1,67 @@
const { describe, test, beforeEach, afterEach, after, mock } = require('node:test');
const assert = require('node:assert');
const crypto = require('crypto');
const baoConf = require('@simpleworkjs/bao-conf');
const Table = require('../../models/index');
const DnsProvider = Table.models.DnsProvider;
const DuckDns = require('../../models/dns_provider/duckdns');
describe('DnsProvider Vault Integration', () => {
let originalSet, originalGet, originalRequest;
after(async () => {
if (Table._redis && Table._redis.quit) {
await Table._redis.quit();
}
});
beforeEach(() => {
// Mock baoConf
originalSet = baoConf.set;
originalGet = baoConf.get;
originalRequest = baoConf.request;
const vaultStore = {};
baoConf.set = mock.fn(async (path, data) => { vaultStore[path] = data; return true; });
baoConf.get = mock.fn(async (path) => vaultStore[path] || {});
baoConf.request = mock.fn(async () => ({}));
mock.method(DuckDns.prototype, 'listDomains', async () => []);
mock.method(DnsProvider.prototype, 'updateDomains', async () => {});
});
afterEach(() => {
baoConf.set = originalSet;
baoConf.get = originalGet;
baoConf.request = originalRequest;
mock.restoreAll();
});
test('create() writes isPrivate keys to OpenBao and get() retrieves them', async () => {
const payload = {
name: 'My Duck',
dnsProvider: 'DuckDns',
token: 'super-secret-vault-token',
subdomains: 'myduck',
created_by: 'admin'
};
const instance = await DnsProvider.create(payload);
// 1. Should have called OpenBao set
assert.strictEqual(baoConf.set.mock.callCount(), 1);
const [path, secrets] = baoConf.set.mock.calls[0].arguments;
assert.strictEqual(path, `proxy/dns-providers/${instance.id}`);
assert.deepStrictEqual(secrets, { token: 'super-secret-vault-token' });
// 2. The returned instance should have the secret injected back
assert.strictEqual(instance.token, 'super-secret-vault-token');
// 3. get() should fetch public data from Redis and merge secrets from OpenBao
// (baoConf.get is already mocked to return from vaultStore)
const fetched = await DnsProvider.get(instance.id);
assert.strictEqual(fetched.token, 'super-secret-vault-token');
});
});