fix: アカウント削除の際にもそのアカウント関連の設定値を削除するように

This commit is contained in:
kakkokari-gtyih 2025-12-27 15:29:54 +09:00
parent 4afcb58a64
commit e2920db7d4
5 changed files with 27 additions and 18 deletions

View File

@ -55,10 +55,15 @@ export async function removeAccount(host: string, id: AccountWithToken['id']) {
const accountInfos = JSON.parse(JSON.stringify(store.s.accountInfos)); const accountInfos = JSON.parse(JSON.stringify(store.s.accountInfos));
delete accountInfos[host + '/' + id]; delete accountInfos[host + '/' + id];
store.set('accountInfos', accountInfos); store.set('accountInfos', accountInfos);
prefer.commit('accounts', prefer.s.accounts.filter(x => x[0] !== host || x[1].id !== id)); prefer.commit('accounts', prefer.s.accounts.filter(x => x[0] !== host || x[1].id !== id));
} }
export async function removeAccountData(host: string, id: AccountWithToken['id']) {
// 設定・状態を削除
prefer.clearAccountSettingsFromDevice(host, id);
await store.clearAccountDataFromDevice(id);
}
const isAccountDeleted = Symbol('isAccountDeleted'); const isAccountDeleted = Symbol('isAccountDeleted');
function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Promise<Misskey.entities.MeDetailed> { function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Promise<Misskey.entities.MeDetailed> {
@ -176,6 +181,7 @@ export async function refreshAccounts() {
} catch (e) { } catch (e) {
if (e === isAccountDeleted) { if (e === isAccountDeleted) {
await removeAccount(account.host, account.id); await removeAccount(account.host, account.id);
await removeAccountData(account.host, account.id);
} }
} }
} }

View File

@ -223,12 +223,15 @@ export class Pizzax<T extends StateDef> {
} }
/** 現在のアカウントに紐づくデータをデバイスから削除します */ /** 現在のアカウントに紐づくデータをデバイスから削除します */
public async clearCurrentAccountDataFromDevice() { public async clearAccountDataFromDevice(id = $i?.id) {
if ($i == null) return; if (id == null) return;
const deviceAccountStateKey = `pizzax::${this.key}::${id}` satisfies typeof this.deviceAccountStateKeyName;
const registryCacheKey = `pizzax::${this.key}::cache::${id}` satisfies typeof this.registryCacheKeyName;
// deviceAccount // deviceAccount
{ const deviceAccountState = await get(deviceAccountStateKey);
const deviceAccountState = await get(this.deviceAccountStateKeyName) || {}; if (deviceAccountState != null) {
let changed = false; let changed = false;
for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) { for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) {
if (v.where === 'deviceAccount' && Object.prototype.hasOwnProperty.call(deviceAccountState, k)) { if (v.where === 'deviceAccount' && Object.prototype.hasOwnProperty.call(deviceAccountState, k)) {
@ -238,14 +241,14 @@ export class Pizzax<T extends StateDef> {
} }
if (changed) { if (changed) {
await this.addIdbSetJob(async () => { await this.addIdbSetJob(async () => {
await set(this.deviceAccountStateKeyName, deviceAccountState); await set(deviceAccountStateKey, deviceAccountState);
}); });
} }
} }
// account (cacheを消す) // account (cacheを消す)
{ const registryCache = await get(registryCacheKey);
const registryCache = await get(this.registryCacheKeyName) || {}; if (registryCache != null) {
let changed = false; let changed = false;
for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) { for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) {
if (v.where === 'account' && Object.prototype.hasOwnProperty.call(registryCache, k)) { if (v.where === 'account' && Object.prototype.hasOwnProperty.call(registryCache, k)) {
@ -255,7 +258,7 @@ export class Pizzax<T extends StateDef> {
} }
if (changed) { if (changed) {
await this.addIdbSetJob(async () => { await this.addIdbSetJob(async () => {
await set(this.registryCacheKeyName, registryCache); await set(registryCacheKey, registryCache);
}); });
} }
} }

View File

@ -37,7 +37,7 @@ import type { MenuItem } from '@/types/menu.js';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { $i } from '@/i.js'; import { $i } from '@/i.js';
import { switchAccount, removeAccount, getAccountWithSigninDialog, getAccountWithSignupDialog, getAccounts, refreshAccounts } from '@/accounts.js'; import { switchAccount, removeAccount, removeAccountData, getAccountWithSigninDialog, getAccountWithSignupDialog, getAccounts, refreshAccounts } from '@/accounts.js';
import type { AccountData } from '@/accounts.js'; import type { AccountData } from '@/accounts.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { definePage } from '@/page.js'; import { definePage } from '@/page.js';
@ -93,6 +93,7 @@ function showMenu(a: AccountData, ev: MouseEvent) {
if (canceled) return; if (canceled) return;
await os.promiseDialog((async () => { await os.promiseDialog((async () => {
await removeAccount(a.host, a.id); await removeAccount(a.host, a.id);
await removeAccountData(a.host, a.id);
accounts.value = await getAccounts(); accounts.value = await getAccounts();
})()); })());
}, },
@ -121,7 +122,7 @@ async function addExistingAccount() {
} }
async function createAccount() { async function createAccount() {
const res = await getAccountWithSignupDialog() const res = await getAccountWithSignupDialog();
if (res != null) { if (res != null) {
os.success(); os.success();
} }

View File

@ -449,10 +449,9 @@ export class PreferencesManager extends EventEmitter<PreferencesManagerEvents> {
this.save(); this.save();
} }
/** 現在の操作アカウントに紐づく設定値をデバイスから削除します(ログアウト時) */ /** 現在の操作アカウントに紐づく設定値をデバイスから削除します(ログアウト時などに使用) */
public clearCurrentAccountSettingsFromDevice() { public clearAccountSettingsFromDevice(targetHost = host, id = this.currentAccount?.id) {
const currentAccount = this.currentAccount; // TSを黙らせるため if (id == null) return;
if (currentAccount == null) return;
let changed = false; let changed = false;
@ -462,7 +461,7 @@ export class PreferencesManager extends EventEmitter<PreferencesManagerEvents> {
const index = records.findIndex((record: PrefRecord<typeof key>) => { const index = records.findIndex((record: PrefRecord<typeof key>) => {
const scope = parseScope(record[0]); const scope = parseScope(record[0]);
return scope.server === host && scope.account === currentAccount.id; return scope.server === targetHost && scope.account === id;
}); });
if (index === -1) continue; if (index === -1) continue;

View File

@ -79,8 +79,8 @@ async function removeCurrentAccountData() {
if ($i == null) return; if ($i == null) return;
// 設定・状態を削除 // 設定・状態を削除
prefer.clearCurrentAccountSettingsFromDevice(); prefer.clearAccountSettingsFromDevice();
await store.clearCurrentAccountDataFromDevice(); await store.clearAccountDataFromDevice();
} }
export async function signout(all = false) { export async function signout(all = false) {