@ -152,7 +152,7 @@
< div class = "text-blue-500 text-sm font-bold" >
< router -link : to = "{ path: '/did/' + encodeURIComponent(activeDid) }" >
Activity
Your Activity
< / r o u t e r - l i n k >
< / div >
< / div >
@ -216,7 +216,6 @@
< div class = "mb-2 font-bold" > Location < / div >
< router -link
: to = "{ name: 'search-area' }"
v - if = "activeDid"
class = "block w-full text-center text-m bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2 mt-6"
>
Set Search Area …
@ -622,6 +621,26 @@
< / button >
< / div >
< div class = "flex justify-between" >
< span >
< span class = "text-slate-500 text-sm font-bold mb-2" >
Passkey Expiration Minutes
< / span >
< br / >
< span class = "text-sm ml-2" >
{ { passkeyExpirationDescription } }
< / span >
< / span >
< div class = "relative ml-2" >
< input
type = "number"
class = "border border-slate-400 rounded px-2 py-2 text-center w-20"
v - model = "passkeyExpirationMinutes"
@ change = "updatePasskeyExpiration"
/ >
< / div >
< / div >
< label
for = "toggleShowGeneralAdvanced"
class = "flex items-center justify-between cursor-pointer mt-4"
@ -667,7 +686,7 @@ import ImageMethodDialog from "@/components/ImageMethodDialog.vue";
import QuickNav from "@/components/QuickNav.vue" ;
import TopMessage from "@/components/TopMessage.vue" ;
import {
AppString ,
AppString , DEFAULT_ENDORSER_API_SERVER ,
DEFAULT_IMAGE_API_SERVER ,
DEFAULT_PUSH_SERVER ,
IMAGE_TYPE_PROFILE ,
@ -675,14 +694,20 @@ import {
} from "@/constants/app" ;
import { db , accountsDB } from "@/db/index" ;
import { Account } from "@/db/tables/accounts" ;
import { MASTER_SETTINGS_KEY , Settings } from "@/db/tables/settings" ;
import { accessToken } from "@/libs/crypto" ;
import {
DEFAULT_PASSKEY_EXPIRATION_MINUTES ,
MASTER_SETTINGS_KEY ,
Settings ,
} from "@/db/tables/settings" ;
import {
clearPasskeyToken ,
ErrorResponse ,
EndorserRateLimits ,
ImageRateLimits ,
fetchEndorserRateLimits ,
fetchImageRateLimits ,
getHeaders ,
ImageRateLimits ,
tokenExpiryTimeDescription ,
} from "@/libs/endorserServer" ;
import { getAccount } from "@/libs/util" ;
@ -713,6 +738,9 @@ export default class AccountViewView extends Vue {
limitsMessage = "" ;
loadingLimits = false ;
notificationMaybeChanged = false ;
passkeyExpirationDescription = "" ;
passkeyExpirationMinutes = DEFAULT_PASSKEY_EXPIRATION_MINUTES ;
previousPasskeyExpirationMinutes = DEFAULT_PASSKEY_EXPIRATION_MINUTES ;
profileImageUrl ? : string ;
publicHex = "" ;
publicBase64 = "" ;
@ -745,12 +773,32 @@ export default class AccountViewView extends Vue {
await this . initializeState ( ) ;
await this . processIdentity ( ) ;
this . passkeyExpirationDescription = tokenExpiryTimeDescription ( ) ;
/ * *
* Beware ! I ' ve seen where this "ready" never resolves .
* /
const registration = await navigator . serviceWorker . ready ;
this . subscription = await registration . pushManager . getSubscription ( ) ;
this . isSubscribed = ! ! this . subscription ;
console . log ( "Got to the end of 'mounted' call." ) ;
/ * *
* Beware ! I ' ve seen where we never get to this point because "ready" never resolves .
* /
} catch ( error ) {
console . error ( "Mount error:" , error ) ;
this . handleError ( error ) ;
console . error (
"Telling user to clear cache at page create because:" ,
error ,
) ;
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Loading Account" ,
text : "Clear your cache and start over (after data backup)." ,
} ,
- 1 ,
) ;
}
}
@ -780,6 +828,10 @@ export default class AccountViewView extends Vue {
this . showContactGives = ! ! settings ? . showContactGivesInline ;
this . hideRegisterPromptOnNewContact =
! ! settings ? . hideRegisterPromptOnNewContact ;
this . passkeyExpirationMinutes =
( settings ? . passkeyExpirationMinutes as number ) ? ?
DEFAULT_PASSKEY_EXPIRATION_MINUTES ;
this . previousPasskeyExpirationMinutes = this . passkeyExpirationMinutes ;
this . showGeneralAdvanced = ! ! settings ? . showGeneralAdvanced ;
this . showShortcutBvc = ! ! settings ? . showShortcutBvc ;
this . warnIfProdServer = ! ! settings ? . warnIfProdServer ;
@ -835,11 +887,11 @@ export default class AccountViewView extends Vue {
this . publicHex = identity . keys [ 0 ] . publicKeyHex ;
this . publicBase64 = Buffer . from ( this . publicHex , "hex" ) . toString ( "base64" ) ;
this . derivationPath = identity . keys [ 0 ] . meta ? . derivationPath as string ;
this . checkLimitsFor ( this . activeDid ) ;
await this . checkLimitsFor ( this . activeDid ) ;
} else if ( account ? . publicKeyHex ) {
this . publicHex = account . publicKeyHex as string ;
this . publicBase64 = Buffer . from ( this . publicHex , "hex" ) . toString ( "base64" ) ;
this . checkLimitsFor ( this . activeDid ) ;
await this . checkLimitsFor ( this . activeDid ) ;
}
}
@ -868,75 +920,18 @@ export default class AccountViewView extends Vue {
this . notificationMaybeChanged = true ;
}
/ * *
* Handles errors and updates the component ' s state accordingly .
* @ param { Error } err - The error object .
* /
handleError ( err : unknown ) {
if (
err instanceof Error &&
err . message ===
"Attempted to load account records with no identifier available."
) {
this . limitsMessage = "No identifier." ;
} else {
console . error ( "Telling user to clear cache at page create because:" , err ) ;
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Loading Account" ,
text : "Clear your cache and start over (after data backup)." ,
} ,
- 1 ,
) ;
}
}
public async updateShowContactAmounts ( ) {
try {
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
showContactGivesInline : this . showContactGives ,
} ) ;
} catch ( err ) {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Updating Contact Setting" ,
text : "The setting may not have saved. Try again, maybe after restarting the app." ,
} ,
- 1 ,
) ;
console . error (
"Telling user to try again after contact-amounts setting update because:" ,
err ,
) ;
}
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
showContactGivesInline : this . showContactGives ,
} ) ;
}
public async updateShowGeneralAdvanced ( ) {
try {
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
showGeneralAdvanced : this . showGeneralAdvanced ,
} ) ;
} catch ( err ) {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Updating Advanced Setting" ,
text : "The setting may not have saved. Try again, maybe after restarting the app." ,
} ,
- 1 ,
) ;
console . error (
"Telling user to try again after general-advanced setting update because:" ,
err ,
) ;
}
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
showGeneralAdvanced : this . showGeneralAdvanced ,
} ) ;
}
public async updateWarnIfProdServer ( newSetting : boolean ) {
@ -963,71 +958,35 @@ export default class AccountViewView extends Vue {
}
public async updateWarnIfTestServer ( newSetting : boolean ) {
try {
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
warnIfTestServer : newSetting ,
} ) ;
} catch ( err ) {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Updating Test Warning" ,
text : "The setting may not have saved. Try again, maybe after restarting the app." ,
} ,
- 1 ,
) ;
console . error (
"Telling user to try again after test-server-warning setting update because:" ,
err ,
) ;
}
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
warnIfTestServer : newSetting ,
} ) ;
}
public async toggleHideRegisterPromptOnNewContact ( ) {
const newSetting = ! this . hideRegisterPromptOnNewContact ;
try {
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
hideRegisterPromptOnNewContact : newSetting ,
} ) ;
this . hideRegisterPromptOnNewContact = newSetting ;
} catch ( err ) {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Updating Setting" ,
text : "The setting may not have saved. Try again, maybe after restarting the app." ,
} ,
- 1 ,
) ;
console . error ( "Telling user to try again because:" , err ) ;
}
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
hideRegisterPromptOnNewContact : newSetting ,
} ) ;
this . hideRegisterPromptOnNewContact = newSetting ;
}
public async updatePasskeyExpiration ( ) {
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
passkeyExpirationMinutes : this . passkeyExpirationMinutes ,
} ) ;
clearPasskeyToken ( ) ;
this . passkeyExpirationDescription = tokenExpiryTimeDescription ( ) ;
}
public async updateShowShortcutBvc ( newSetting : boolean ) {
try {
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
showShortcutBvc : newSetting ,
} ) ;
} catch ( err ) {
this . $notify (
{
group : "alert" ,
type : "danger" ,
title : "Error Updating BVC Shortcut Setting" ,
text : "The setting may not have saved. Try again, maybe after restarting the app." ,
} ,
- 1 ,
) ;
console . error (
"Telling user to try again after BVC-shortcut setting update because:" ,
err ,
) ;
}
await db . open ( ) ;
await db . settings . update ( MASTER_SETTINGS_KEY , {
showShortcutBvc : newSetting ,
} ) ;
}
/ * *
@ -1220,7 +1179,7 @@ export default class AccountViewView extends Vue {
/ / t h e u s e r w a s n o t k n o w n t o b e r e g i s t e r e d , b u t n o w t h e y a r e ( b e c a u s e w e g o t n o e r r o r ) s o l e t ' s r e c o r d i t
try {
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
isRegistered : true ,
} ) ;
this . isRegistered = true ;
@ -1247,7 +1206,7 @@ export default class AccountViewView extends Vue {
try {
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
isRegistered : false ,
} ) ;
this . isRegistered = false ;
@ -1272,8 +1231,8 @@ export default class AccountViewView extends Vue {
( data ? . error ? . message as string ) || "Bad server response." ;
console . error (
"Got bad response retrieving limits, which usually means user isn't registered." ,
error ,
) ;
/ / c o n s o l e . e r r o r ( e r r o r ) ;
} else {
this . limitsMessage = "Got an error retrieving limits." ;
console . error ( "Got some error retrieving limits:" , error ) ;
@ -1350,7 +1309,7 @@ export default class AccountViewView extends Vue {
async onClickSaveApiServer ( ) {
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
apiServer : this . apiServerInput ,
} ) ;
this . apiServer = this . apiServerInput ;
@ -1358,7 +1317,7 @@ export default class AccountViewView extends Vue {
async onClickSavePushServer ( ) {
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
webPushServer : this . webPushServerInput ,
} ) ;
this . webPushServer = this . webPushServerInput ;
@ -1377,7 +1336,7 @@ export default class AccountViewView extends Vue {
( this . $refs . imageMethodDialog as ImageMethodDialog ) . open (
async ( imgUrl ) => {
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
profileImageUrl : imgUrl ,
} ) ;
this . profileImageUrl = imgUrl ;
@ -1407,16 +1366,13 @@ export default class AccountViewView extends Vue {
return ;
}
try {
const token = await accessToken ( this . activeDid ) ;
const headers = await getHeaders ( this . activeDid ) ;
this . passkeyExpirationDescription = tokenExpiryTimeDescription ( ) ;
const response = await this . axios . delete (
DEFAULT_IMAGE_API_SERVER +
"/image/" +
encodeURIComponent ( this . profileImageUrl ) ,
{
headers : {
Authorization : ` Bearer ${ token } ` ,
} ,
} ,
{ headers } ,
) ;
if ( response . status === 204 ) {
/ / d o n ' t b o t h e r w i t h a n o t i f i c a t i o n
@ -1436,7 +1392,7 @@ export default class AccountViewView extends Vue {
}
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
profileImageUrl : undefined ,
} ) ;
@ -1448,7 +1404,7 @@ export default class AccountViewView extends Vue {
console . error ( "The image was already deleted:" , error ) ;
await db . open ( ) ;
db . settings . update ( MASTER_SETTINGS_KEY , {
await db . settings . update ( MASTER_SETTINGS_KEY , {
profileImageUrl : undefined ,
} ) ;