+70
web-ui/src/lib/components/RotationKeyDisplay.svelte
+70
web-ui/src/lib/components/RotationKeyDisplay.svelte
···
1
+
<script lang="ts">
2
+
let {handle, multiBasePrivateKey} = $props();
3
+
import {handleAndPDSResolver} from '@pds-moover/moover'
4
+
5
+
const copyToClipboard = async (text: string) => {
6
+
try {
7
+
await navigator.clipboard.writeText(text);
8
+
alert('Copied to clipboard');
9
+
} catch (e) {
10
+
console.error(e);
11
+
alert('Failed to copy to clipboard');
12
+
}
13
+
}
14
+
15
+
const downloadNewRotationKey = async (rotationKey: string, handle: string) => {
16
+
if (!rotationKey) return;
17
+
18
+
19
+
//try and find the did to add to the file as well
20
+
let didText = '';
21
+
try {
22
+
let {usersDid} = await handleAndPDSResolver(handle);
23
+
didText = `DID: ${usersDid}\n`;
24
+
} catch (e) {
25
+
//sliently log. Rather the user have their rotation key than not. a did can always be found other ways if needed
26
+
console.error(e);
27
+
}
28
+
29
+
30
+
const content = `You can use these to recover your account if it's ever necessary via https://pdsmoover.com/restore. The restore process will ask for the Private key\n\nKEEP IN A SECURE LOCATION\n\n${didText}PublicKey: ${rotationKey.publicKey}\nPrivateKey: ${rotationKey.privateKey}\n`;
31
+
const blob = new Blob([content], {type: 'text/plain'});
32
+
const url = URL.createObjectURL(blob);
33
+
const a = document.createElement('a');
34
+
a.href = url;
35
+
36
+
37
+
a.download = `${handle}-rotation-key.txt`;
38
+
document.body.appendChild(a);
39
+
a.click();
40
+
document.body.removeChild(a);
41
+
URL.revokeObjectURL(url);
42
+
}
43
+
</script>
44
+
45
+
46
+
<div class="section" style="margin-top: 16px; border: 2px solid #f39c12; padding: 16px;">
47
+
<h3 style="color: #d35400;">Important: Save Your New Rotation Key Now</h3>
48
+
<p style="color: #c0392b; font-weight: bold;">
49
+
Warning: This is the only time we will show you your private rotation key. Save it in a secure place.
50
+
If you lose it, you may not be able to recover your account in the event of a PDS failure or hijack.
51
+
</p>
52
+
<div class="form-group">
53
+
<label>New Rotation Key (Private - keep secret)</label>
54
+
<div style="display:flex; gap:8px; align-items:center;">
55
+
{#if multiBasePrivateKey}
56
+
<code
57
+
style="overflow-wrap:anywhere;">{multiBasePrivateKey}</code>
58
+
{/if}
59
+
60
+
<button type="button"
61
+
onclick={async () => await copyToClipboard(multiBasePrivateKey)}>Copy
62
+
</button>
63
+
</div>
64
+
</div>
65
+
<div class="form-group">
66
+
<button type="button" onclick={async () => await downloadNewRotationKey(multiBasePrivateKey, handle)}>Download
67
+
Key File
68
+
</button>
69
+
</div>
70
+
</div>
+11
-3
web-ui/src/routes/moover/+page.svelte
+11
-3
web-ui/src/routes/moover/+page.svelte
···
29
29
let showTwoFactorCodeInput = $state(false);
30
30
let showAdvance = $state(false);
31
31
let showStatusMessage = $state(false);
32
-
let askForPlcToken = $state(true);
32
+
let askForPlcToken = $state(false);
33
+
let disableSubmit = $state(false);
33
34
34
35
let errorMessage: null | string = $state(null);
35
36
···
43
44
44
45
async function submitMoove(event: SubmitEvent & { currentTarget: EventTarget & HTMLFormElement }) {
45
46
event.preventDefault();
47
+
disableSubmit = true;
46
48
errorMessage = null;
47
49
showStatusMessage = false;
48
50
49
51
if (!formData.confirmation) {
50
52
errorMessage = 'Please confirm that you understand the risks of doing an account migration';
53
+
disableSubmit = false;
51
54
return;
52
55
}
53
56
···
56
59
if (showTwoFactorCodeInput) {
57
60
if (showTwoFactorCodeInput === null) {
58
61
errorMessage = 'Please enter the 2FA that was sent to your email.'
62
+
disableSubmit = false;
63
+
return;
59
64
}
60
65
}
61
66
···
83
88
formData.twoFactorCode,
84
89
);
85
90
if (migrator.migratePlcRecord) {
91
+
//I don't think disable submit is needed, but you never know.
92
+
disableSubmit = false;
86
93
askForPlcToken = true;
87
94
} else {
88
95
updateStatusHandler('Migration of your repo is complete! But the PLC operation was not done so your old account is still the valid one.');
89
96
}
90
97
} catch (error) {
98
+
disableSubmit = false;
91
99
console.error(error);
92
100
//@ts-expect-error: JS being js. doesn't like not having the type'
93
101
if (error.error === 'AuthFactorTokenRequired') {
···
107
115
108
116
<div class="container">
109
117
<MooHeader title="PDS MOOver"/>
110
-
<button onclick={() => askForPlcToken = !askForPlcToken}>I'm not a cow</button>
118
+
<!-- <button onclick={() => askForPlcToken = !askForPlcToken}>I'm not a cow</button>-->
111
119
112
120
{#if !askForPlcToken}
113
121
<a href={resolve('/info')}>Idk if I trust a cow to move my atproto account to a new PDS</a>
···
255
263
{/if}
256
264
257
265
<div>
258
-
<button type="submit">MOOve</button>
266
+
<button disabled={disableSubmit} type="submit">MOOve</button>
259
267
</div>
260
268
</form>
261
269
{:else}
+3
web-ui/src/routes/moover/SignThePapers.svelte
+3
web-ui/src/routes/moover/SignThePapers.svelte
···
31
31
// Generate a new rotation key if requested
32
32
if (createANewRotationKey) {
33
33
34
+
//TODO write the new component and should be about ready to test
35
+
36
+
34
37
//TODO this will become a prop to the new component
35
38
// window.handle = this.newHandle;
36
39
let plcOps = new PlcOps();
web-ui/src/routes/rotation-key/+page.svelte
web-ui/src/routes/rotation-key/+page.svelte
This is a binary file and will not be displayed.