Browse Source

Create a client using existing public key

pull/2556/head
Dvorhack 3 months ago
parent
commit
32b9be3208
  1. 4
      src/app/components/Clients/CreateDialog.vue
  2. 2
      src/app/components/Form/TextField.vue
  3. 1
      src/i18n/locales/en.json
  4. 4
      src/server/api/client/index.post.ts
  5. 15
      src/server/database/repositories/client/service.ts
  6. 7
      src/server/database/repositories/client/types.ts

4
src/app/components/Clients/CreateDialog.vue

@ -14,6 +14,7 @@
v-model="expiresAt"
:label="$t('client.expireDate')"
/>
<FormTextField id="publicKey" v-model="publicKey" :label="$t('client.publicKey')" placeholder="AAAAAAAAAA=" />
</div>
</template>
<template #actions>
@ -32,6 +33,7 @@
<script lang="ts" setup>
const name = ref<string>('');
const expiresAt = ref<string | null>(null);
const publicKey = ref<string | null>(null);
const clientsStore = useClientsStore();
const { t } = useI18n();
@ -39,7 +41,7 @@ const { t } = useI18n();
defineProps<{ triggerClass?: string }>();
function createClient() {
return _createClient({ name: name.value, expiresAt: expiresAt.value });
return _createClient({ name: name.value, expiresAt: expiresAt.value, publicKey: publicKey.value || undefined });
}
const _createClient = useSubmit(

2
src/app/components/Form/TextField.vue

@ -14,6 +14,7 @@
type="text"
:autocomplete="autocomplete"
:disabled="disabled"
:placeholder="placeholder"
/>
</template>
@ -24,6 +25,7 @@ defineProps<{
description?: string;
autocomplete?: string;
disabled?: boolean;
placeholder?: string;
}>();
const data = defineModel<string>();

1
src/i18n/locales/en.json

@ -87,6 +87,7 @@
"new": "New Client",
"name": "Name",
"expireDate": "Expire Date",
"publicKey": "Existing WireGuard Public Key (Optional)",
"expireDateDesc": "Date the client will be disabled. Blank for permanent",
"delete": "Delete",
"deleteClient": "Delete Client",

4
src/server/api/client/index.post.ts

@ -4,12 +4,12 @@ export default definePermissionEventHandler(
'clients',
'create',
async ({ event }) => {
const { name, expiresAt } = await readValidatedBody(
const { name, expiresAt, publicKey } = await readValidatedBody(
event,
validateZod(ClientCreateSchema, event)
);
const result = await Database.clients.create({ name, expiresAt });
const result = await Database.clients.create({ name, expiresAt, publicKey });
await WireGuard.saveConfig();
const clientId = result[0]!.clientId;

15
src/server/database/repositories/client/service.ts

@ -168,9 +168,18 @@ export class ClientService {
return this.#statements.findById.execute({ id });
}
async create({ name, expiresAt }: ClientCreateType) {
const privateKey = await wg.generatePrivateKey();
const publicKey = await wg.getPublicKey(privateKey);
async create({ name, expiresAt, publicKey: providedPublicKey }: ClientCreateType) {
let privateKey: string | undefined;
let publicKey: string;
if (providedPublicKey) {
publicKey = providedPublicKey;
privateKey = 'REDACTED';
} else {
privateKey = await wg.generatePrivateKey();
publicKey = await wg.getPublicKey(privateKey);
}
const preSharedKey = await wg.generatePreSharedKey();
return this.#db.transaction(async (tx) => {

7
src/server/database/repositories/client/types.ts

@ -28,6 +28,12 @@ const expiresAt = z
.min(1, t('zod.client.expiresAt'))
.pipe(safeStringRefine)
.nullable();
const publicKey = z
.string({ message: t('zod.client.publicKey') })
.min(1, t('zod.client.publicKey'))
.pipe(safeStringRefine)
.optional();
const address4 = z
.string({ message: t('zod.client.address4') })
@ -48,6 +54,7 @@ const serverAllowedIps = z.array(AddressSchema, {
export const ClientCreateSchema = z.object({
name: name,
expiresAt: expiresAt,
publicKey: publicKey
});
export type ClientCreateType = z.infer<typeof ClientCreateSchema>;

Loading…
Cancel
Save