cache the passkey JWANT access token for multiple signatures

This commit is contained in:
2024-07-19 12:44:54 -06:00
parent cd0a31e6f5
commit b2ebc2992b
11 changed files with 196 additions and 219 deletions

View File

@@ -85,7 +85,7 @@ export const generateSeed = (): string => {
};
/**
* Retreive an access token
* Retrieve an access token, or "" if no DID is provided.
*
* @return {*}
*/

View File

@@ -5,9 +5,10 @@ import * as R from "ramda";
import { DEFAULT_IMAGE_API_SERVER } from "@/constants/app";
import { Contact } from "@/db/tables/contacts";
import { accessToken } from "@/libs/crypto";
import { NonsensitiveDexie } from "@/db/index";
import { getAccount } from "@/libs/util";
import { db, NonsensitiveDexie } from "@/db/index";
import { getAccount, getPasskeyExpirationSeconds } from "@/libs/util";
import { createEndorserJwtForKey, KeyMeta } from "@/libs/crypto/vc";
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
export const SCHEMA_ORG_CONTEXT = "https://schema.org";
// the object in RegisterAction claims
@@ -447,12 +448,57 @@ export function didInfo(
return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
}
let passkeyAccessToken: string = "";
let passkeyTokenExpirationEpochSeconds: number = 0;
export function clearPasskeyToken() {
passkeyAccessToken = "";
passkeyTokenExpirationEpochSeconds = 0;
}
export function tokenExpiryTimeDescription() {
if (
!passkeyAccessToken ||
passkeyTokenExpirationEpochSeconds < new Date().getTime() / 1000
) {
return "Token has expired";
} else {
return (
"Token expires at " +
new Date(passkeyTokenExpirationEpochSeconds * 1000).toLocaleString()
);
}
}
/**
* Get the headers for a request, potentially including Authorization
*/
export async function getHeaders(did?: string) {
const headers: { "Content-Type": string; Authorization?: string } = {
"Content-Type": "application/json",
};
if (did) {
const token = await accessToken(did);
let token;
const account = await getAccount(did);
if (account?.passkeyCredIdHex) {
if (
passkeyAccessToken &&
passkeyTokenExpirationEpochSeconds > Date.now() / 1000
) {
// there's an active current passkey token
token = passkeyAccessToken;
} else {
// there's no current passkey token or it's expired
token = await accessToken(did);
passkeyAccessToken = token;
const passkeyExpirationSeconds = await getPasskeyExpirationSeconds();
passkeyTokenExpirationEpochSeconds =
Date.now() / 1000 + passkeyExpirationSeconds;
}
} else {
token = await accessToken(did);
}
headers["Authorization"] = "Bearer " + token;
} else {
// it's often OK to request without auth; we assume necessary checks are done earlier

View File

@@ -1,21 +1,20 @@
// many of these are also found in endorser-mobile utility.ts
import axios, { AxiosResponse } from "axios";
import { IIdentifier } from "@veramo/core";
import { useClipboard } from "@vueuse/core";
import { DEFAULT_PUSH_SERVER } from "@/constants/app";
import { accountsDB, db } from "@/db/index";
import { Account } from "@/db/tables/accounts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import {DEFAULT_PASSKEY_EXPIRATION_MINUTES, MASTER_SETTINGS_KEY} from "@/db/tables/settings";
import { deriveAddress, generateSeed, newIdentifier } from "@/libs/crypto";
import { GenericCredWrapper, containsHiddenDid } from "@/libs/endorserServer";
import * as serverUtil from "@/libs/endorserServer";
import { registerCredential } from "@/libs/crypto/vc/passkeyDidPeer";
import { Buffer } from "buffer";
import {KeyMeta} from "@/libs/crypto/vc";
import {createPeerDid} from "@/libs/crypto/vc/didPeer";
import { KeyMeta } from "@/libs/crypto/vc";
import { createPeerDid } from "@/libs/crypto/vc/didPeer";
export const PRIVACY_MESSAGE =
"The data you send will be visible to the world -- except: your IDs and the IDs of anyone you tag will stay private, only visible to them and others you explicitly allow.";
@@ -273,6 +272,15 @@ export const registerSaveAndActivatePasskey = async (
return account;
};
export const getPasskeyExpirationSeconds = async (): Promise<number> => {
await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
const passkeyExpirationSeconds =
(settings?.passkeyExpirationMinutes ?? DEFAULT_PASSKEY_EXPIRATION_MINUTES) *
60;
return passkeyExpirationSeconds;
};
export const sendTestThroughPushServer = async (
subscriptionJSON: PushSubscriptionJSON,
skipFilter: boolean,