forked from snxraven/peardock
Ship remaining roadmap items: encrypted registry vault, peer invite/revoke, Swarm/plugins behind flags, binary streams, engine create validation, deploy rollback, schema validation, fleet/access UI, metrics, fuzz/load/soak tests, systemd packaging, and release tooling. Mark ROADMAP fully complete.
75 lines
2.3 KiB
JavaScript
75 lines
2.3 KiB
JavaScript
/**
|
|
* Registry credential vault RPC handlers.
|
|
*/
|
|
import * as vault from '../core/registry-vault.js'
|
|
import * as validation from '../utils/validation.js'
|
|
import { docker } from '../services/docker.js'
|
|
import logger from '../utils/logger.js'
|
|
|
|
export function registerVaultHandlers(session) {
|
|
session.respond('listVaultCredentials', async () => {
|
|
return {
|
|
success: true,
|
|
type: 'vaultCredentials',
|
|
data: vault.listCredentials(),
|
|
}
|
|
})
|
|
|
|
session.respond('vaultStoreCredential', async (args) => {
|
|
const username = validation.sanitizeString(args.username, 128)
|
|
const password = args.password
|
|
const serveraddress = validation.sanitizeString(
|
|
args.serveraddress || 'https://index.docker.io/v1/',
|
|
512
|
|
)
|
|
if (!username || !password) throw new Error('username and password required')
|
|
|
|
// Optional verify against engine
|
|
if (args.verify !== false) {
|
|
try {
|
|
await new Promise((resolve, reject) => {
|
|
docker.checkAuth({ username, password, serveraddress }, (err, res) =>
|
|
err ? reject(err) : resolve(res)
|
|
)
|
|
})
|
|
} catch (err) {
|
|
if (args.requireAuth) throw new Error(`Auth failed: ${err.message}`)
|
|
logger.warn('vault store: checkAuth soft-fail', { error: err.message })
|
|
}
|
|
}
|
|
|
|
const stored = vault.storeCredential({
|
|
id: args.id,
|
|
username,
|
|
password,
|
|
serveraddress,
|
|
label: args.label || username,
|
|
})
|
|
return { success: true, message: 'Credential stored encrypted at rest', data: stored }
|
|
})
|
|
|
|
session.respond('vaultDeleteCredential', async (args) => {
|
|
if (!args.id) throw new Error('credential id required')
|
|
return vault.deleteCredential(args.id)
|
|
})
|
|
|
|
session.respond('vaultUseCredential', async (args) => {
|
|
if (!args.id) throw new Error('credential id required')
|
|
const cred = vault.getCredential(args.id)
|
|
if (!cred) throw new Error('Credential not found')
|
|
session.state.set('registryAuth', {
|
|
username: cred.username,
|
|
password: cred.password,
|
|
serveraddress: cred.serveraddress,
|
|
})
|
|
return {
|
|
success: true,
|
|
message: `Using vault credential for ${cred.username}`,
|
|
data: {
|
|
username: cred.username,
|
|
serveraddress: cred.serveraddress,
|
|
},
|
|
}
|
|
})
|
|
}
|