This commit is contained in:
Andras Bacsai 2022-11-23 15:44:30 +01:00
parent d4f10a9af3
commit d61671c1a0
5 changed files with 102 additions and 41 deletions

View File

@ -3,7 +3,7 @@ import { X509Certificate } from 'node:crypto';
import type { FastifyReply, FastifyRequest } from 'fastify'; import type { FastifyReply, FastifyRequest } from 'fastify';
import { asyncExecShell, checkDomainsIsValidInDNS, decrypt, encrypt, errorHandler, isDev, isDNSValid, isDomainConfigured, listSettings, prisma } from '../../../../lib/common'; import { asyncExecShell, checkDomainsIsValidInDNS, decrypt, encrypt, errorHandler, isDev, isDNSValid, isDomainConfigured, listSettings, prisma } from '../../../../lib/common';
import { CheckDNS, CheckDomain, DeleteDomain, OnlyIdInBody, SaveSettings, SaveSSHKey } from './types'; import { CheckDNS, CheckDomain, DeleteDomain, OnlyIdInBody, SaveSettings, SaveSSHKey, SetDefaultRegistry } from './types';
export async function listAllSettings(request: FastifyRequest) { export async function listAllSettings(request: FastifyRequest) {
@ -11,8 +11,20 @@ export async function listAllSettings(request: FastifyRequest) {
const teamId = request.user.teamId; const teamId = request.user.teamId;
const settings = await listSettings(); const settings = await listSettings();
const sshKeys = await prisma.sshKey.findMany({ where: { team: { id: teamId } } }) const sshKeys = await prisma.sshKey.findMany({ where: { team: { id: teamId } } })
const publicRegistries = await prisma.dockerRegistry.findMany({ where: { isSystemWide: true } }) let publicRegistries = await prisma.dockerRegistry.findMany({ where: { isSystemWide: true } })
const registries = await prisma.dockerRegistry.findMany({ where: { team: { id: teamId } } }) let privateRegistries = await prisma.dockerRegistry.findMany({ where: { team: { id: teamId } } })
publicRegistries = publicRegistries.map((registry) => {
if (registry.password) {
registry.password = decrypt(registry.password)
}
return registry
})
privateRegistries = privateRegistries.map((registry) => {
if (registry.password) {
registry.password = decrypt(registry.password)
}
return registry
})
const unencryptedKeys = [] const unencryptedKeys = []
if (sshKeys.length > 0) { if (sshKeys.length > 0) {
for (const key of sshKeys) { for (const key of sshKeys) {
@ -32,7 +44,7 @@ export async function listAllSettings(request: FastifyRequest) {
sshKeys: unencryptedKeys, sshKeys: unencryptedKeys,
registries: { registries: {
public: publicRegistries, public: publicRegistries,
private: registries private: privateRegistries
} }
} }
} catch ({ status, message }) { } catch ({ status, message }) {
@ -155,3 +167,22 @@ export async function deleteCertificates(request: FastifyRequest<OnlyIdInBody>,
return errorHandler({ status, message }) return errorHandler({ status, message })
} }
} }
export async function setDockerRegistry(request: FastifyRequest<SetDefaultRegistry>, reply: FastifyReply) {
try {
const teamId = request.user.teamId;
const { id, username, password } = request.body;
let encryptedPassword = ''
if (password) encryptedPassword = encrypt(password)
if (teamId === '0') {
await prisma.dockerRegistry.update({ where: { id }, data: { username, password: encryptedPassword } })
} else {
await prisma.dockerRegistry.updateMany({ where: { id, teamId }, data: { username, password: encryptedPassword } })
}
return reply.code(201).send()
} catch ({ status, message }) {
return errorHandler({ status, message })
}
}

View File

@ -2,8 +2,8 @@ import { FastifyPluginAsync } from 'fastify';
import { X509Certificate } from 'node:crypto'; import { X509Certificate } from 'node:crypto';
import { encrypt, errorHandler, prisma } from '../../../../lib/common'; import { encrypt, errorHandler, prisma } from '../../../../lib/common';
import { checkDNS, checkDomain, deleteCertificates, deleteDomain, deleteSSHKey, listAllSettings, saveSettings, saveSSHKey } from './handlers'; import { checkDNS, checkDomain, deleteCertificates, deleteDomain, deleteSSHKey, listAllSettings, saveSettings, saveSSHKey, setDockerRegistry } from './handlers';
import { CheckDNS, CheckDomain, DeleteDomain, OnlyIdInBody, SaveSettings, SaveSSHKey } from './types'; import { CheckDNS, CheckDomain, DeleteDomain, OnlyIdInBody, SaveSettings, SaveSSHKey, SetDefaultRegistry } from './types';
const root: FastifyPluginAsync = async (fastify): Promise<void> => { const root: FastifyPluginAsync = async (fastify): Promise<void> => {
@ -20,6 +20,9 @@ const root: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.post<SaveSSHKey>('/sshKey', async (request, reply) => await saveSSHKey(request, reply)); fastify.post<SaveSSHKey>('/sshKey', async (request, reply) => await saveSSHKey(request, reply));
fastify.delete<OnlyIdInBody>('/sshKey', async (request, reply) => await deleteSSHKey(request, reply)); fastify.delete<OnlyIdInBody>('/sshKey', async (request, reply) => await deleteSSHKey(request, reply));
fastify.post<SetDefaultRegistry>('/registry', async (request, reply) => await setDockerRegistry(request, reply));
// fastify.delete<>('/registry', async (request, reply) => await deleteSSHKey(request, reply));
fastify.post('/upload', async (request) => { fastify.post('/upload', async (request) => {
try { try {
const teamId = request.user.teamId; const teamId = request.user.teamId;
@ -53,7 +56,6 @@ const root: FastifyPluginAsync = async (fastify): Promise<void> => {
}); });
fastify.delete<OnlyIdInBody>('/certificate', async (request, reply) => await deleteCertificates(request, reply)) fastify.delete<OnlyIdInBody>('/certificate', async (request, reply) => await deleteCertificates(request, reply))
// fastify.get('/certificates', async (request) => await getCertificates(request))
}; };
export default root; export default root;

View File

@ -48,3 +48,11 @@ export interface OnlyIdInBody {
id: string id: string
} }
} }
export interface SetDefaultRegistry {
Body: {
id: string
username: string
password: string
}
}

View File

@ -15,7 +15,7 @@
export let placeholder = ''; export let placeholder = '';
export let inputStyle = ''; export let inputStyle = '';
let disabledClass = 'bg-coolback disabled:bg-coolblack w-full'; let disabledClass = 'input input-primary bg-coolback disabled:bg-coolblack w-full';
let isHttps = browser && window.location.protocol === 'https:'; let isHttps = browser && window.location.protocol === 'https:';
function copyToClipboard() { function copyToClipboard() {

View File

@ -20,16 +20,17 @@
export let registries: any; export let registries: any;
import { del, post } from '$lib/api'; import { del, post } from '$lib/api';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
const publicRegistries = registries.public; const publicRegistries = registries.public;
const privateRegistries = registries.private; const privateRegistries = registries.private;
let isModalActive = false; let isModalActive = false;
let newRegistry = { let newRegistry = {
name: null, name: '',
username: null, username: '',
password: null, password: '',
url: null, url: '',
isSystemWide: false isSystemWide: false
}; };
@ -43,6 +44,11 @@
return false; return false;
} }
} }
async function setRegistry(registry: any) {
try {
await post(`/settings/registry`, registry);
} catch (error) {}
}
async function deleteSSHKey(id: string) { async function deleteSSHKey(id: string) {
const sure = confirm('Are you sure you would like to delete this SSH key?'); const sure = confirm('Are you sure you would like to delete this SSH key?');
if (sure) { if (sure) {
@ -83,10 +89,27 @@
<tr> <tr>
<td>{registry.name}</td> <td>{registry.name}</td>
<td>{(registry.isSystemWide && 'Yes') || 'No'}</td> <td>{(registry.isSystemWide && 'Yes') || 'No'}</td>
<td>{registry.username ?? 'N/A'}</td>
<td>{registry.password ?? 'N/A'}</td>
<td> <td>
<CopyPasswordField
name="username"
id="Username"
bind:value={registry.username}
placeholder="Username"
/></td
>
<td
><CopyPasswordField
isPasswordField={true}
name="Password"
id="Password"
bind:value={registry.password}
placeholder="Password"
/></td
>
<td>
<button on:click={() => setRegistry(registry)} class="btn btn-sm btn-primary"
>Set</button
>
{#if !registry.isSystemWide} {#if !registry.isSystemWide}
<button on:click={() => deleteSSHKey(registry.id)} class="btn btn-sm btn-error" <button on:click={() => deleteSSHKey(registry.id)} class="btn btn-sm btn-error"
>Delete</button >Delete</button
@ -126,44 +149,41 @@
<label for="name" class="label"> <label for="name" class="label">
<span class="label-text">Name</span> <span class="label-text">Name</span>
</label> </label>
<input <CopyPasswordField
id="name" id="name"
type="text" name="name"
bind:value={newRegistry.name} bind:value={newRegistry.name}
placeholder="Docker Registry Name" placeholder="Docker Registry Name"
class="input input-primary w-full bg-coolgray-100"
required required
/> />
<label for="url" class="label"> <label for="url" class="label">
<span class="label-text">URL</span> <span class="label-text">URL</span>
</label> </label>
<input <CopyPasswordField
id="url" id="url"
type="text" name="url"
bind:value={newRegistry.url} bind:value={newRegistry.url}
placeholder="Docker Registry URL" placeholder="Docker Registry URL"
class="input input-primary w-full bg-coolgray-100"
required required
/> />
<label for="Username" class="label"> <label for="Username" class="label">
<span class="label-text">Username</span> <span class="label-text">Username</span>
</label> </label>
<input <CopyPasswordField
id="Username" id="Username"
type="text" name="username"
bind:value={newRegistry.username} bind:value={newRegistry.username}
placeholder="Username" placeholder="Username"
class="input input-primary w-full bg-coolgray-100"
/> />
<label for="Password" class="label"> <label for="Password" class="label">
<span class="label-text">Password</span> <span class="label-text">Password</span>
</label> </label>
<input <CopyPasswordField
isPasswordField={true}
id="Password" id="Password"
type="text" name="password"
bind:value={newRegistry.password} bind:value={newRegistry.password}
placeholder="Password" placeholder="Password"
class="input input-primary w-full bg-coolgray-100"
/> />
<div class="flex items-center"> <div class="flex items-center">
<label for="systemwide" class="label"> <label for="systemwide" class="label">