Skip to content

Commit

Permalink
Support account delete
Browse files Browse the repository at this point in the history
  • Loading branch information
asika32764 committed May 20, 2024
1 parent 78ef30f commit fef67a3
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
VITE_BASE_URL=
VITE_API_ENDPOINT=https://authman.io/api/v1
VITE_API_ENDPOINT=
VITE_TEST_USERNAME=
VITE_TEST_PASSWORD=
VITE_TEST_REGISTER_USERNAME=
Expand Down
4 changes: 3 additions & 1 deletion src/components/account/edit/LogoSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ async function resizeImage(imgDataUri: string) {
<div style="margin-bottom: .5rem; width: 100%; display: flex; justify-content: center">
<ion-searchbar autocapitalize="none" v-model="q" placeholder="Search Icon (FontAwesome)"
color="medium"
style="" />
style=""
@keyup.enter="searchIcon"
/>
</div>

<ion-button @click="searchIcon" fill="outline" color="dark"
Expand Down
6 changes: 0 additions & 6 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ import './theme/main.scss';

currentPlatforms.value = getPlatforms();

console.log(
isElectron.value,
electronService.getMode(),
isElectron.value ? electronService.getMode() : undefined
);

const app = createApp(App)
.use(IonicVue, {
mode: isElectron.value ? electronService.getMode() : undefined
Expand Down
5 changes: 5 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ const routes: Array<RouteRecordRaw> = [
name: 'about',
component: () => import('@/views/options/AboutPage.vue'),
},
{
path: 'profile',
name: 'profile',
component: () => import('@/views/options/ProfilePage.vue'),
},
],
},
];
Expand Down
5 changes: 5 additions & 0 deletions src/service/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ axios.interceptors.response.use(
}
}

// User not found.
if (errCode === 40106) {
return userService.logoutAndRedirect();
}

const json = e.response?.data;

if (json?.message) {
Expand Down
80 changes: 80 additions & 0 deletions src/service/user-delete-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import apiClient from '@/service/api-client';
import authService from '@/service/auth-service';
import localAuthService from '@/service/local-auth-service';
import userService from '@/service/user-service';
import { userStorage } from '@/store/main-store';
import { simpleActionSheetConfirm, simpleAlert } from '@/utilities/alert';
import { useLoadingOverlay } from '@/utilities/loading';
import { hexToBigint } from '@windwalker-io/srp';
import { bigintToHex } from 'bigint-toolkit';

export default new class {
async deleteMeAndLogout() {
await this.deleteMe();

await userService.logoutAndRedirect();
}

async deleteMe() {
const v = await simpleActionSheetConfirm(
'This action cannot redo.',
[
'Delete It',
'Cancel',
],
{
subHeader: 'Do you really want to delete account?'
}
);

if (!v) {
return;
}

const password = await userService.askPassword(
'Your Password',
'Please enter master password again'
);

if (!password) {
return;
}

const kek = await localAuthService.validatePasswordAndGetKek(password);

if (!kek) {
simpleAlert('Invalid password.');
return;
}

const { loading, run } = await useLoadingOverlay('Deleting account...');

await run(async () => {
const user = userStorage.value!;
const { salt, B, sess } = await authService.challenge(user.email);

const { A, M1, S } = await authService.runSRPLoginSteps(
user.email,
password,
hexToBigint(salt),
hexToBigint(B),
);

return this.deleteAccount(A, M1, sess);
});
}

async deleteAccount(A: bigint, M1: bigint, sess: string) {
const user = userStorage.value!;

return apiClient.post(
'auth/delete/me',
{
email: user.email,
A: bigintToHex(A),
M1: bigintToHex(M1),
sess,
}
);
}
}
20 changes: 16 additions & 4 deletions src/service/user-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ export default new class UserService {
{
type: 'password',
name: 'password',
id: 'input-password'
id: 'input-password',
attributes: {
autocomplete: 'off'
}
},
],
buttons: [
Expand All @@ -187,7 +190,7 @@ export default new class UserService {
],
...options
})
.then((alert) => {
.then(async (alert) => {
alert.onDidDismiss().then((e) => {
if (e.role === 'backdrop' || e.role === 'cancel') {
resolve(false);
Expand All @@ -200,10 +203,19 @@ export default new class UserService {
return e;
});

return alert.present();
await alert.present();

return alert;
})
.then((alert) => {
document.querySelector<HTMLInputElement>('#input-password')?.focus();
const input = document.querySelector<HTMLInputElement>('#input-password')!;
input.focus();
input.addEventListener('keypress', (e: KeyboardEvent) => {
if (e.key === 'Enter' && input.value !== '') {
alert.dismiss();
resolve(input.value);
}
});

return alert;
});
Expand Down
20 changes: 16 additions & 4 deletions src/utilities/alert.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { actionSheetController, alertController, toastController, ToastOptions } from '@ionic/vue';
import {
actionSheetController,
ActionSheetOptions,
alertController,
toastController,
ToastOptions,
} from '@ionic/vue';

export async function simpleAlert(title: any, text?: string, type = 'warning'): Promise<void> {
if (title instanceof Error || title.message) {
Expand Down Expand Up @@ -54,7 +60,11 @@ export async function simpleConfirm(title: string, text?: string): Promise<boole
});
}

export async function simpleActionSheetConfirm(title: string, buttons: string[] = []): Promise<boolean> {
export async function simpleActionSheetConfirm(
title: string,
buttons: string[] = [],
options: Partial<ActionSheetOptions> = {}
): Promise<boolean> {
return new Promise((resolve) => {
const alert = actionSheetController
.create({
Expand All @@ -76,6 +86,7 @@ export async function simpleActionSheetConfirm(title: string, buttons: string[]
},
},
],
...options
});

alert.then((alert) => alert.present());
Expand All @@ -86,13 +97,14 @@ export async function simpleToast(
message: string,
position: 'top' | 'bottom' | 'middle' = 'bottom',
duration = 1000,
options: ToastOptions = {}
options: ToastOptions = {},
) {
const toast = await toastController.create({
...options,
message,
position,
duration
duration,
swipeGesture: 'vertical',
});

return toast.present();
Expand Down
66 changes: 19 additions & 47 deletions src/views/OptionsPage.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
<script setup lang="ts">
import icon from '@/assets/images/icon.svg';
import MainLayout from '@/components/layout/MainLayout.vue';
import exportService from '@/service/export-service';
import importService from '@/service/import-service';
import localAuthService from '@/service/local-auth-service';
import lockScreenService from '@/service/lock-screen-service';
import userService from '@/service/user-service';
import { isElectron, noInstantUnlock, userStorage } from '@/store/main-store';
import { noInstantUnlock, userStorage } from '@/store/main-store';
import { enableBiometricsOption } from '@/store/options-store';
import { simpleActionSheetConfirm, simpleConfirm } from '@/utilities/alert';
import { simpleActionSheetConfirm } from '@/utilities/alert';
import { Share } from '@capacitor/share';
import { faUser } from '@fortawesome/free-regular-svg-icons';
import {
faDownload,
faEnvelope, faFileExport, faFileImport,
faFingerprint,
faKey,
faLock,
faShareNodes,
faSignOut, faUpload, faUserAlt,
faSignOut,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { IonImg, IonItem, IonLabel, IonList, IonNote, IonToggle, useIonRouter } from '@ionic/vue';
import { watch } from 'vue';
const user = userStorage.value;
const router = useIonRouter();
const user = userStorage.value!;
watch(enableBiometricsOption, async (v) => {
if (v) {
Expand All @@ -46,29 +43,21 @@ function lockScreen() {
router.navigate(
{ name: 'lock' },
'forward',
'push'
'push',
);
}
async function importAccounts() {
await importService.import();
}
async function exportAccounts() {
await exportService.export();
}
async function share() {
await Share.share({
title: 'Authman App',
url: import.meta.env.VITE_INFO_WEBSITE
url: import.meta.env.VITE_INFO_WEBSITE,
});
}
async function logout() {
const v = await simpleActionSheetConfirm(
'Do you want to logout?',
['Logout', 'Cancel']
['Logout', 'Cancel'],
);
if (v) {
Expand All @@ -83,11 +72,21 @@ async function logout() {
<ion-list style="" inset>
<!-- About -->
<ion-item button router-link="about">
<ion-img :src="icon" slot="start" style="height: 1.5rem; width: 1.5rem;" />
<ion-img :src="icon" slot="start"
style="height: 1.5rem; width: 1.5rem; margin-inline-end: .7rem; margin-inline-start: -5px" />
<ion-label>
About Authman
</ion-label>
</ion-item>

<!-- My Account -->
<ion-item button router-link="profile">
<FontAwesomeIcon :icon="faUser" slot="start" />
<ion-label>
<h4>My Account</h4>
<ion-note>{{ user?.email }}</ion-note>
</ion-label>
</ion-item>
</ion-list>

<ion-list style="" inset>
Expand Down Expand Up @@ -122,33 +121,6 @@ async function logout() {
</ion-item>
</ion-list>

<ion-list style="" inset>
<!-- Email -->
<ion-item>
<FontAwesomeIcon :icon="faUserAlt" slot="start" />
<ion-label>
<h4>My Email</h4>
<ion-note>{{ user.email }}</ion-note>
</ion-label>
</ion-item>

<!-- Import -->
<ion-item button @click="importAccounts">
<FontAwesomeIcon :icon="faUpload" slot="start" />
<ion-label>
Import
</ion-label>
</ion-item>

<!-- Export -->
<ion-item button @click="exportAccounts">
<FontAwesomeIcon :icon="faDownload" slot="start" />
<ion-label>
Export
</ion-label>
</ion-item>
</ion-list>

<ion-list inset>
<!-- Share -->
<ion-item button @click="share">
Expand Down
1 change: 1 addition & 0 deletions src/views/auth/RegistrationPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ async function register() {
message: 'Your account created.',
position: 'top',
duration: 3000,
swipeGesture: 'vertical'
});
toast.present();
Expand Down
Loading

0 comments on commit fef67a3

Please sign in to comment.