Skip to content

Commit e83a351

Browse files
Implement key management on the frontend
1 parent 64462a2 commit e83a351

File tree

4 files changed

+155
-48
lines changed

4 files changed

+155
-48
lines changed

src/routes/admin/+page.server.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@ import { getPortfolioGlobals } from '$lib/server';
22
import { redirectOnInvalidToken } from '$lib/server/auth/tokens';
33
import { dataDirUsesGit } from '$lib/server/data/dataDir';
44
import { getRepoStatus } from '$lib/server/git';
5+
import { getPrivateKeyPath, getPublicKey } from '$lib/server/keys.js';
56

67
export async function load(req: import('./$types.js').RequestEvent) {
78
const globals = await getPortfolioGlobals();
89
await redirectOnInvalidToken(req, '/admin/login');
910
const repo = await dataDirUsesGit() ? await getRepoStatus() : null;
10-
return { globals, repo };
11+
return {
12+
globals,
13+
repo,
14+
keys: {
15+
publicKey: await getPublicKey(),
16+
keyPath: await getPrivateKeyPath(),
17+
}
18+
};
1119
}

src/routes/admin/+page.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import GitSettings from './GitSettings.svelte';
77
import ChangePassword from './ChangePassword.svelte';
88
import ReloadData from './ReloadData.svelte';
9-
import LogOutAll from './LogOutAll.svelte';
9+
import LogOutAll from './LogOutAll.svelte';
10+
import KeySettings from './KeySettings.svelte';
1011
1112
export let data: import('./$types').PageData;
1213
</script>
@@ -32,6 +33,10 @@
3233
<Paper>
3334
<div id="contents">
3435
<GitSettings {data} />
36+
<KeySettings
37+
publicKey={data.keys.publicKey}
38+
privateKeyPath={data.keys.keyPath}
39+
/>
3540
<ChangePassword username={'admin'} />
3641
<LogOutAll />
3742
<ReloadData />
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<!-- Settings panel for managing the server's public key. -->
2+
<script lang="ts">
3+
import CopyButton from '$components/CopyButton.svelte';
4+
import api from '$endpoints';
5+
import { APP_NAME } from '$lib/consts';
6+
7+
/** Public key currently being used by the server */
8+
export let publicKey: string | null;
9+
/** Path to the server's private key */
10+
export let privateKeyPath: string | null;
11+
12+
/** Setting key path */
13+
let newKeyPath = '';
14+
15+
/** Use the SSH key at the given path */
16+
async function useKeyAtPath() {
17+
const newKey = await api().admin.keys.setKeyPath(newKeyPath);
18+
publicKey = newKey.publicKey;
19+
privateKeyPath = newKey.keyPath;
20+
newKeyPath = '';
21+
}
22+
23+
/** Generate a new SSH key */
24+
async function generateNewKey() {
25+
const newKey = await api().admin.keys.generate();
26+
publicKey = newKey.publicKey;
27+
privateKeyPath = newKey.keyPath;
28+
}
29+
30+
/** Use system SSH keys */
31+
async function useSystemSsh() {
32+
await api().admin.keys.disable();
33+
publicKey = null;
34+
privateKeyPath = null;
35+
}
36+
</script>
37+
38+
<div>
39+
<h2>SSH key settings</h2>
40+
{#if privateKeyPath === null}
41+
<p>
42+
{APP_NAME} is using your system's default SSH configuration. Note that in Docker,
43+
this may be unset, unless you are forwarding your host's SSH agent.
44+
</p>
45+
<form on:submit|preventDefault={useKeyAtPath}>
46+
<p>Use the given SSH key-pair</p>
47+
<p>
48+
<input
49+
type="text"
50+
bind:value={newKeyPath}
51+
placeholder="/path/to/private/key"
52+
/>
53+
</p>
54+
<p><input type="submit" value="Set SSH key path" /></p>
55+
</form>
56+
<form on:submit|preventDefault={generateNewKey}>
57+
<p>Generate a new SSH key-pair</p>
58+
<p><input type="submit" value="Generate SSH key" /></p>
59+
</form>
60+
{:else}
61+
<p>{APP_NAME} is using an SSH key at the path <em>{privateKeyPath}</em>.</p>
62+
63+
<p>Public key is:</p>
64+
<pre>{publicKey}</pre>
65+
<CopyButton text={publicKey ?? ''}>Copy to clipboard</CopyButton>
66+
<form on:submit|preventDefault={useKeyAtPath}>
67+
<p>Use the given SSH key-pair</p>
68+
<p>
69+
<input
70+
type="text"
71+
bind:value={newKeyPath}
72+
placeholder="/path/to/private/key"
73+
/>
74+
</p>
75+
<p><input type="submit" value="Set SSH key path" /></p>
76+
</form>
77+
<form on:submit|preventDefault={generateNewKey}>
78+
<p>Generate a new SSH key-pair</p>
79+
<p><input type="submit" value="Generate SSH key" /></p>
80+
</form>
81+
<form on:submit|preventDefault={useSystemSsh}>
82+
<p>Use the system's SSH configuration</p>
83+
<p><input type="submit" value="Use system SSH" /></p>
84+
</form>
85+
{/if}
86+
</div>
87+
88+
<style>
89+
90+
</style>

src/routes/admin/firstrun/data/+page.svelte

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
import Navbar from '$components/navbar';
1010
import blankConfig from '$lib/blankConfig';
1111
import consts from '$lib/consts';
12+
import KeySettings from '../../KeySettings.svelte';
1213
13-
// TODO: Show info about the public key
14-
// export let data;
14+
export let data;
1515
1616
// Default values are auto-filled in dev mode
1717
let repoUrl = dev ? 'git@github.com:MaddyGuthridge/portfolio-data.git' : '';
@@ -87,49 +87,53 @@
8787
{/if}
8888
</div>
8989

90-
<form on:submit={onSubmit}>
91-
<h3>Data repository URL</h3>
92-
<p>
93-
It's a good idea to set up a repository to back up your portfolio
94-
data.
95-
<a
96-
href="https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository"
97-
target="_blank">Create an empty git repository</a
98-
>
99-
and enter the clone URL here. If you want to import existing data, enter
100-
your existing repository URL here.
101-
</p>
102-
<input
103-
type="text"
104-
id="repo-url"
105-
bind:value={repoUrl}
106-
placeholder="git@github.com:MaddyGuthridge/portfolio-data.git"
107-
/>
108-
109-
<h3>Repository branch</h3>
110-
<p>If you want to use a specific branch, you can enter it here.</p>
111-
<input
112-
type="text"
113-
id="repo-branch"
114-
bind:value={repoBranch}
115-
placeholder="main"
116-
/>
117-
118-
<h3>Ready to get started?</h3>
119-
<input type="submit" id="submit-main" value="Let's go!" />
120-
121-
<h3>Don't want to use a git repo?</h3>
122-
<p>
123-
Using a git repo is a great idea if you want your data to be safely
124-
backed up. But if you're just testing {consts.APP_NAME}, it's much
125-
quicker to get started without a git repo.
126-
</p>
127-
<input
128-
type="submit"
129-
id="submit-no-git"
130-
value="I don't want to use git"
131-
/>
132-
</form>
90+
<div class="main-content">
91+
<KeySettings publicKey={data.publicKey} privateKeyPath={data.keyPath} />
92+
93+
<form on:submit={onSubmit}>
94+
<h3>Data repository URL</h3>
95+
<p>
96+
It's a good idea to set up a repository to back up your portfolio
97+
data.
98+
<a
99+
href="https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository"
100+
target="_blank">Create an empty git repository</a
101+
>
102+
and enter the clone URL here. If you want to import existing data, enter
103+
your existing repository URL here.
104+
</p>
105+
<input
106+
type="text"
107+
id="repo-url"
108+
bind:value={repoUrl}
109+
placeholder="git@github.com:MaddyGuthridge/portfolio-data.git"
110+
/>
111+
112+
<h3>Repository branch</h3>
113+
<p>If you want to use a specific branch, you can enter it here.</p>
114+
<input
115+
type="text"
116+
id="repo-branch"
117+
bind:value={repoBranch}
118+
placeholder="main"
119+
/>
120+
121+
<h3>Ready to get started?</h3>
122+
<input type="submit" id="submit-main" value="Let's go!" />
123+
124+
<h3>Don't want to use a git repo?</h3>
125+
<p>
126+
Using a git repo is a great idea if you want your data to be safely
127+
backed up. But if you're just testing {consts.APP_NAME}, it's much
128+
quicker to get started without a git repo.
129+
</p>
130+
<input
131+
type="submit"
132+
id="submit-no-git"
133+
value="I don't want to use git"
134+
/>
135+
</form>
136+
</div>
133137
</main>
134138
</Paper>
135139
</div>
@@ -162,7 +166,7 @@
162166
margin: 20px;
163167
}
164168
165-
form {
169+
.main-content {
166170
margin: 0 10%;
167171
}
168172

0 commit comments

Comments
 (0)