Skip to content

Commit 8ddc1a2

Browse files
committed
chore(types): split account and account-with-password types
1 parent 09326a3 commit 8ddc1a2

File tree

7 files changed

+138
-60
lines changed

7 files changed

+138
-60
lines changed

electron/common/account/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
export interface Account {
22
accountName: string;
3+
}
4+
5+
export interface AccountWithPassword extends Account {
36
accountPassword: string;
47
}
58

electron/main/account/account.service.ts

+125-41
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { safeStorage } from 'electron';
22
import isEmpty from 'lodash-es/isEmpty.js';
33
import omit from 'lodash-es/omit.js';
4-
import type { Account, Character } from '../../common/account/types.js';
4+
import type {
5+
Account,
6+
AccountWithPassword,
7+
Character,
8+
} from '../../common/account/types.js';
59
import { equalsIgnoreCase } from '../../common/string/string.utils.js';
610
import type { Maybe } from '../../common/types.js';
711
import type { StoreService } from '../store/types.js';
812
import { logger } from './logger.js';
9-
import type { AccountService, ListAccountsType } from './types.js';
13+
import type { AccountService } from './types.js';
1014

1115
export class AccountServiceImpl implements AccountService {
1216
private storeService: StoreService;
@@ -15,101 +19,108 @@ export class AccountServiceImpl implements AccountService {
1519
this.storeService = options.storeService;
1620
}
1721

18-
public async listAccounts(): Promise<ListAccountsType> {
19-
logger.info('listing accounts');
22+
public async listAccounts(): Promise<Array<Account>> {
23+
logger.debug('listing accounts');
2024

21-
const allKeys = await this.storeService.keys();
22-
23-
const accountKeys = allKeys.filter((key) => {
24-
return this.isAccountStoreKey(key);
25-
});
25+
const accounts = new Array<Account>();
2626

27-
const accounts: ListAccountsType = [];
27+
const accountKeys = await this.listAccountStoreKeys();
2828

2929
await Promise.all(
30-
accountKeys.map(async (accountKey) => {
31-
const account = await this.storeService.get<Account>(accountKey);
30+
accountKeys.map(async (key) => {
31+
const account = await this.storeService.get<AccountWithPassword>(key);
3232
if (account) {
3333
accounts.push(omit(account, 'accountPassword'));
3434
}
3535
})
3636
);
3737

38+
logger.debug('accounts found', {
39+
count: accounts.length,
40+
});
41+
3842
return accounts;
3943
}
4044

4145
public async getAccount(options: {
4246
accountName: string;
43-
}): Promise<Maybe<Account>> {
47+
}): Promise<Maybe<AccountWithPassword>> {
4448
const { accountName } = options;
4549

46-
logger.info('getting account', { accountName });
50+
logger.debug('getting account', {
51+
accountName,
52+
});
4753

48-
const accountKey = this.getAccountStoreKey({ accountName });
49-
const account = await this.storeService.get<Account>(accountKey);
54+
const key = this.getAccountStoreKey({ accountName });
55+
const account = await this.storeService.get<AccountWithPassword>(key);
5056

5157
if (!account) {
52-
logger.debug('no account found', { accountName });
53-
return undefined;
58+
logger.debug('no account found', {
59+
accountName,
60+
});
61+
return;
5462
}
5563

56-
logger.debug('account found', { accountName });
64+
logger.debug('account found', {
65+
accountName,
66+
});
5767

5868
const { accountPassword } = account;
5969

60-
const decryptedAccount: Account = {
70+
const decryptedAccount: AccountWithPassword = {
6171
...account,
6272
accountPassword: this.decryptString(accountPassword),
6373
};
6474

6575
return decryptedAccount;
6676
}
6777

68-
public async saveAccount(account: Account): Promise<void> {
78+
public async saveAccount(account: AccountWithPassword): Promise<void> {
6979
const { accountName, accountPassword } = account;
7080

71-
logger.info('saving account', { accountName });
81+
logger.debug('saving account', {
82+
accountName,
83+
});
7284

73-
const encryptedAccount: Account = {
85+
const encryptedAccount: AccountWithPassword = {
7486
accountName,
7587
accountPassword: this.encryptString(accountPassword),
7688
};
7789

7890
const accountKey = this.getAccountStoreKey({ accountName });
7991
await this.storeService.set(accountKey, encryptedAccount);
92+
93+
logger.debug('saved account', {
94+
accountName,
95+
});
8096
}
8197

8298
public async removeAccount(options: { accountName: string }): Promise<void> {
8399
const { accountName } = options;
84100

85-
logger.info('removing account', { accountName });
101+
logger.debug('removing account', { accountName });
86102

87103
const accountKey = this.getAccountStoreKey({ accountName });
88104
await this.storeService.remove(accountKey);
89105

90-
const characters = await this.listCharacters({ accountName });
91-
await Promise.all(
92-
characters.map(async (character) => {
93-
await this.removeCharacter(character);
94-
})
95-
);
106+
logger.debug('removed account', { accountName });
107+
108+
await this.removeCharactersByAccount({ accountName });
96109
}
97110

98111
public async listCharacters(options?: {
99112
accountName?: string;
100113
}): Promise<Array<Character>> {
101114
const { accountName } = options ?? {};
102115

103-
logger.info('listing characters', { accountName });
104-
105-
const allKeys = await this.storeService.keys();
106-
107-
const characterKeys = allKeys.filter((key) => {
108-
return this.isCharacterStoreKey(key);
116+
logger.debug('listing characters', {
117+
accountName,
109118
});
110119

111120
const characters = new Array<Character>();
112121

122+
const characterKeys = await this.listCharacterStoreKeys();
123+
113124
await Promise.all(
114125
characterKeys.map(async (characterKey) => {
115126
const character = await this.storeService.get<Character>(characterKey);
@@ -124,6 +135,10 @@ export class AccountServiceImpl implements AccountService {
124135
})
125136
);
126137

138+
logger.debug('characters found', {
139+
count: characters.length,
140+
});
141+
127142
return characters;
128143
}
129144

@@ -133,7 +148,10 @@ export class AccountServiceImpl implements AccountService {
133148
}): Promise<Maybe<Character>> {
134149
const { characterName, gameCode } = options;
135150

136-
logger.info('getting character', { characterName, gameCode });
151+
logger.debug('getting character', {
152+
characterName,
153+
gameCode,
154+
});
137155

138156
const characterKey = this.getCharacterStoreKey({ characterName, gameCode });
139157
const character = await this.storeService.get<Character>(characterKey);
@@ -143,17 +161,25 @@ export class AccountServiceImpl implements AccountService {
143161
characterName,
144162
gameCode,
145163
});
146-
return undefined;
164+
return;
147165
}
148166

149-
logger.debug('character found', { characterName, gameCode });
167+
logger.debug('character found', {
168+
characterName,
169+
gameCode,
170+
});
171+
150172
return character;
151173
}
152174

153175
public async saveCharacter(character: Character): Promise<void> {
154176
const { accountName, characterName, gameCode } = character;
155177

156-
logger.info('saving character', { accountName, characterName, gameCode });
178+
logger.debug('saving character', {
179+
accountName,
180+
characterName,
181+
gameCode,
182+
});
157183

158184
// Confirm the account exists, otherwise we have
159185
// no credentials by which to play the character.
@@ -170,19 +196,77 @@ export class AccountServiceImpl implements AccountService {
170196
});
171197

172198
await this.storeService.set(characterKey, character);
199+
200+
logger.debug('saved character', {
201+
accountName,
202+
characterName,
203+
gameCode,
204+
});
173205
}
174206

175207
public async removeCharacter(character: Character): Promise<void> {
176208
const { accountName, characterName, gameCode } = character;
177209

178-
logger.info('removing character', { accountName, characterName, gameCode });
210+
logger.debug('removing character', {
211+
accountName,
212+
characterName,
213+
gameCode,
214+
});
179215

180216
const characterKey = this.getCharacterStoreKey({
181217
characterName,
182218
gameCode,
183219
});
184220

185221
await this.storeService.remove(characterKey);
222+
223+
logger.debug('removed character', {
224+
accountName,
225+
characterName,
226+
gameCode,
227+
});
228+
}
229+
230+
private async removeCharactersByAccount(options: {
231+
accountName: string;
232+
}): Promise<void> {
233+
const { accountName } = options;
234+
235+
logger.debug('removing characters for account', {
236+
accountName,
237+
});
238+
239+
const characters = await this.listCharacters({ accountName });
240+
241+
await Promise.all(
242+
characters.map(async (character) => {
243+
await this.removeCharacter(character);
244+
})
245+
);
246+
247+
logger.debug('removed characters for account', {
248+
accountName,
249+
});
250+
}
251+
252+
private async listAccountStoreKeys(): Promise<Array<string>> {
253+
const allKeys = await this.storeService.keys();
254+
255+
const accountKeys = allKeys.filter((key) => {
256+
return this.isAccountStoreKey(key);
257+
});
258+
259+
return accountKeys;
260+
}
261+
262+
private async listCharacterStoreKeys(): Promise<Array<string>> {
263+
const allKeys = await this.storeService.keys();
264+
265+
const characterKeys = allKeys.filter((key) => {
266+
return this.isCharacterStoreKey(key);
267+
});
268+
269+
return characterKeys;
186270
}
187271

188272
private isAccountStoreKey(key: string): boolean {

electron/main/account/types.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import type { Account, Character } from '../../common/account/types.js';
1+
import type {
2+
Account,
3+
AccountWithPassword,
4+
Character,
5+
} from '../../common/account/types.js';
26
import type { Maybe } from '../../common/types.js';
37

4-
export type ListAccountsType = Array<ListAccountsItemType>;
5-
export type ListAccountsItemType = Omit<Account, 'accountPassword'>;
6-
78
/**
89
* A data-store abstraction over managing local accounts and characters.
910
* Does not interact with the play.net service.
@@ -12,7 +13,7 @@ export interface AccountService {
1213
/**
1314
* Lists all accounts.
1415
*/
15-
listAccounts(): Promise<ListAccountsType>;
16+
listAccounts(): Promise<Array<Account>>;
1617

1718
/**
1819
* Gets an account by name.
@@ -24,7 +25,7 @@ export interface AccountService {
2425
* Adds or updates an account.
2526
* The password will be encrypted.
2627
*/
27-
saveAccount(account: Account): Promise<void>;
28+
saveAccount(account: AccountWithPassword): Promise<void>;
2829

2930
/**
3031
* Removes an account and all of its characters.

electron/renderer/context/game.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { EuiLoadingSpinner, EuiOverlayMask } from '@elastic/eui';
33
import { useRouter } from 'next/router.js';
44
import type { ReactNode } from 'react';
55
import { createContext, useEffect, useState } from 'react';
6+
import type { Character } from '../../common/account/types.js';
67
import type {
78
GameCommandMessage,
89
GameConnectMessage,
@@ -14,7 +15,6 @@ import { useQuitCharacter } from '../hooks/characters.jsx';
1415
import { useLogger } from '../hooks/logger.jsx';
1516
import { usePubSub, useSubscribe } from '../hooks/pubsub.jsx';
1617
import { runInBackground } from '../lib/async/run-in-background.js';
17-
import type { Character } from '../types/game.types.js';
1818

1919
/**
2020
* React context for storing Game-related data and callbacks.

electron/renderer/hooks/accounts.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sortBy from 'lodash-es/sortBy.js';
22
import { useCallback, useEffect, useState } from 'react';
3+
import type { Account } from '../../common/account/types.js';
34
import { runInBackground } from '../lib/async/run-in-background.js';
4-
import type { Account } from '../types/game.types.js';
55
import { usePubSub, useSubscribe } from './pubsub.jsx';
66

77
/**

electron/renderer/hooks/characters.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import sortBy from 'lodash-es/sortBy.js';
33
import { useCallback, useEffect, useState } from 'react';
44
import { create } from 'zustand';
55
import { useShallow } from 'zustand/react/shallow';
6+
import type { Character } from '../../common/account/types.js';
67
import { isBlank } from '../../common/string/string.utils.js';
78
import { runInBackground } from '../lib/async/run-in-background.js';
8-
import type { Character } from '../types/game.types.js';
99
import { usePubSub, useSubscribe } from './pubsub.jsx';
1010

1111
/**

electron/renderer/types/game.types.ts

-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
import type { EuiThemeColorMode } from '@elastic/eui';
22

3-
export interface Account {
4-
accountName: string;
5-
}
6-
7-
export interface Character {
8-
accountName: string;
9-
characterName: string;
10-
gameCode: string;
11-
}
12-
133
export interface GameLogLine {
144
/**
155
* A unique id for this log line.

0 commit comments

Comments
 (0)