;
promptToStopAsking?: boolean;
+ yesText?: string;
}
diff --git a/src/libs/didPeer.ts b/src/libs/didPeer.ts
index 93a5403..74c8b19 100644
--- a/src/libs/didPeer.ts
+++ b/src/libs/didPeer.ts
@@ -1,4 +1,3 @@
-import asn1 from "asn1-ber";
import { Buffer } from "buffer/";
import { decode as cborDecode } from "cbor-x";
import { bytesToMultibase, JWTPayload, multibaseToBytes } from "did-jwt";
@@ -195,12 +194,12 @@ export class PeerSetup {
allowCredentials: [
{
id: credentialId,
- type: "public-key",
+ type: "public-key" as const,
},
],
challenge: this.challenge.buffer,
rpID: window.location.hostname,
- userVerification: "preferred",
+ userVerification: "preferred" as const,
},
};
@@ -209,7 +208,7 @@ export class PeerSetup {
this.authenticatorData = credential?.response.authenticatorData;
const authenticatorDataBase64Url = arrayBufferToBase64URLString(
- this.authenticatorData,
+ this.authenticatorData as ArrayBuffer,
);
this.clientDataJsonBase64Url = arrayBufferToBase64URLString(
@@ -249,6 +248,9 @@ export class PeerSetup {
return jwt;
}
+ // To use this, add the asn1-ber library and add this import:
+ // import asn1 from "asn1-ber";
+ //
// return a low-level signing function, similar to createJWS approach
// async webAuthnES256KSigner(credentialID: string) {
// return async (data: string | Uint8Array) => {
diff --git a/src/views/IdentitySwitcherView.vue b/src/views/IdentitySwitcherView.vue
index b008fd2..59f0523 100644
--- a/src/views/IdentitySwitcherView.vue
+++ b/src/views/IdentitySwitcherView.vue
@@ -164,7 +164,7 @@ export default class IdentitySwitcherView extends Vue {
group: "modal",
type: "confirm",
title: "Delete Identity?",
- text: "Are you sure you want to permanently delete this identity? (There is no undo.)",
+ text: "Are you sure you want to erase this identity? (There is no undo. You may want to select it and back it up just in case.)",
onYes: async () => {
await accountsDB.open();
await accountsDB.accounts.delete(id);
@@ -185,7 +185,7 @@ export default class IdentitySwitcherView extends Vue {
title: "Cannot Delete",
text: "You cannot delete the active identity.",
},
- 5000,
+ 3000,
);
}
}
diff --git a/src/views/NewEditAccountView.vue b/src/views/NewEditAccountView.vue
index b98fef7..3b6f849 100644
--- a/src/views/NewEditAccountView.vue
+++ b/src/views/NewEditAccountView.vue
@@ -68,8 +68,6 @@ export default class NewEditAccountView extends Vue {
firstName: this.givenName,
lastName: "", // deprecated, pre v 0.1.3
});
- localStorage.setItem("firstName", this.givenName as string);
- localStorage.setItem("lastName", ""); // deprecated, pre v 0.1.3
this.$router.back();
}
diff --git a/src/views/TestView.vue b/src/views/TestView.vue
index aae1918..4c2cbc9 100644
--- a/src/views/TestView.vue
+++ b/src/views/TestView.vue
@@ -176,8 +176,8 @@
See existing passkeys in Chrome at: chrome://settings/passkeys
- Active DID: {{ activeDid }}
- {{ credIdHex ? "has passkey ID" : "has no passkey ID" }}
+ Active DID: {{ activeDid || "nothing, which" }}
+ {{ credIdHex ? "has a passkey ID" : "has no passkey ID" }}
Register Passkey
@@ -244,6 +244,7 @@ import { ref } from "vue";
import { Component, Vue } from "vue-facing-decorator";
import QuickNav from "@/components/QuickNav.vue";
+import { NotificationIface } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import {
createPeerDid,
@@ -269,6 +270,8 @@ const TEST_PAYLOAD = {
@Component({ components: { QuickNav } })
export default class Help extends Vue {
+ $notify!: (notification: NotificationIface, timeout?: number) => void;
+
// for file import
fileName?: string;
@@ -300,7 +303,7 @@ export default class Help extends Vue {
}
async uploadFile(event: Event) {
- inputFileNameRef.value = event.target.files[0];
+ inputFileNameRef.value = event.target?.["files"][0];
// https://developer.mozilla.org/en-US/docs/Web/API/File
// ... plus it has a `type` property from my testing
const file = inputFileNameRef.value;
@@ -330,7 +333,27 @@ export default class Help extends Vue {
}
public async register() {
- const cred = await registerCredential(this.userName);
+ const DEFAULT_USERNAME = "Time Safari Tester";
+ if (!this.userName) {
+ this.$notify(
+ {
+ group: "modal",
+ type: "confirm",
+ title: "No Name",
+ text: "You must have a name to attach to this passkey. Would you like to enter your own name first?",
+ onNo: async () => {
+ this.userName = DEFAULT_USERNAME;
+ },
+ onYes: async () => {
+ this.$router.push({ name: "new-edit-account" });
+ },
+ noText: "try again and use " + DEFAULT_USERNAME,
+ },
+ -1,
+ );
+ return;
+ }
+ const cred = await registerCredential("Time Safari - " + this.userName);
const publicKeyBytes = cred.publicKeyBytes;
this.activeDid = createPeerDid(publicKeyBytes as Uint8Array);
this.credIdHex = cred.credIdHex as string;
diff --git a/vite.config.mjs b/vite.config.mjs
index 7a811df..4e60ee0 100644
--- a/vite.config.mjs
+++ b/vite.config.mjs
@@ -16,6 +16,8 @@ export default defineConfig({
srcDir: '.',
filename: 'sw_scripts-combined.js',
manifest: {
+ // This is used for the app name. It doesn't include a space, because iOS complains if i recall correctly.
+ // There is a name with spaces in the constants/app.js file for use internally.
name: process.env.TIME_SAFARI_APP_TITLE || require('./package.json').name,
short_name: process.env.TIME_SAFARI_APP_TITLE || require('./package.json').name,
// 192x192 and 512x512 are important for Chrome to show that it's installable