mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-02 00:06:23 +00:00
fix: keep a new default-port account apart from a kept host-only one
This commit is contained in:
@@ -49,6 +49,45 @@ describe('generateAccountId', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('a new default-port account next to a kept host-only id', () => {
|
||||
const legacy = { id: 'u@example.org@mail.example.org', username: 'u@example.org', serverUrl: 'https://mail.example.org:8120' };
|
||||
|
||||
it('gets an id of its own instead of the one the other server kept', () => {
|
||||
setKnownAccounts([legacy]);
|
||||
expect(generateAccountId('u@example.org', 'https://mail.example.org')).toBe('u@example.org@mail.example.org:443');
|
||||
expect(generateAccountId('u@example.org', 'http://mail.example.org/jmap')).toBe('u@example.org@mail.example.org:80');
|
||||
// The kept account itself still resolves to its old id.
|
||||
expect(generateAccountId('u@example.org', 'https://mail.example.org:8120')).toBe(legacy.id);
|
||||
});
|
||||
|
||||
it('keeps that id after the other account is gone', () => {
|
||||
const own = { id: 'u@example.org@mail.example.org:443', username: 'u@example.org', serverUrl: 'https://mail.example.org' };
|
||||
setKnownAccounts([legacy, own]);
|
||||
expect(generateAccountId('u@example.org', 'https://mail.example.org')).toBe(own.id);
|
||||
setKnownAccounts([own]);
|
||||
expect(generateAccountId('u@example.org', 'https://mail.example.org')).toBe(own.id);
|
||||
});
|
||||
|
||||
it('leaves an existing default-port account under its plain id', () => {
|
||||
setKnownAccounts([{ id: 'u@example.org@mail.example.org', username: 'u@example.org', serverUrl: 'https://mail.example.org/' }]);
|
||||
expect(generateAccountId('u@example.org', 'https://mail.example.org')).toBe('u@example.org@mail.example.org');
|
||||
});
|
||||
|
||||
it('adds it to the registry as a second account', () => {
|
||||
useAccountStore.setState({
|
||||
accounts: [{ ...entry('u@example.org', legacy.serverUrl), id: legacy.id, avatarColor: '#000', isDefault: true }],
|
||||
activeAccountId: legacy.id,
|
||||
defaultAccountId: legacy.id,
|
||||
});
|
||||
const id = useAccountStore.getState().addAccount(entry('u@example.org', 'https://mail.example.org'));
|
||||
expect(id).toBe('u@example.org@mail.example.org:443');
|
||||
expect(useAccountStore.getState().accounts.map((x) => [x.id, x.serverUrl])).toEqual([
|
||||
[legacy.id, legacy.serverUrl],
|
||||
['u@example.org@mail.example.org:443', 'https://mail.example.org'],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the account registry', () => {
|
||||
it('adds the same address on another port of the same host as a second account', () => {
|
||||
const store = useAccountStore.getState();
|
||||
|
||||
@@ -50,6 +50,11 @@ function hostOnlyAccountId(username: string, serverUrl: string): string {
|
||||
return `${username}@${host}`;
|
||||
}
|
||||
|
||||
/** The default port of `serverUrl`'s scheme: 80 for http, 443 otherwise. */
|
||||
function defaultPortOf(serverUrl: string): string {
|
||||
return /^http:/i.test(serverUrl.trim()) ? '80' : '443';
|
||||
}
|
||||
|
||||
/** What the registry tells generateAccountId (structural: no AccountEntry import). */
|
||||
export interface KnownAccount {
|
||||
id: string;
|
||||
@@ -78,13 +83,22 @@ export function setKnownAccounts(accounts: readonly KnownAccount[]): void {
|
||||
* outbox, push registration and settings: when the registry holds the
|
||||
* host-only id for the same server, that is the answer. A second server on
|
||||
* the same host then gets the id with its port, and the two stay apart.
|
||||
* Accounts on the default ports have the same id either way.
|
||||
* Accounts on the default ports have the same id either way, with one
|
||||
* exception: when the registry holds username@host for a server on another
|
||||
* port of that host (kept from before ports counted), the default-port
|
||||
* server gets username@host:443 (or :80 for http), so the two don't share
|
||||
* credentials and caches. It keeps that id once it has it.
|
||||
*/
|
||||
export function generateAccountId(username: string, serverUrl: string): string {
|
||||
const legacy = hostOnlyAccountId(username, serverUrl);
|
||||
const host = serverHostLabel(serverUrl);
|
||||
const id = `${username}@${host}`;
|
||||
if (id === legacy) return id;
|
||||
if (id === legacy) {
|
||||
const explicit = `${id}:${defaultPortOf(serverUrl)}`;
|
||||
if (knownAccounts.some((a) => a.id === explicit)) return explicit;
|
||||
const taken = knownAccounts.some((a) => a.id === id && `${a.username}@${serverHostLabel(a.serverUrl)}` !== id);
|
||||
return taken ? explicit : id;
|
||||
}
|
||||
const kept = knownAccounts.find((a) => a.id === legacy
|
||||
&& a.username === username
|
||||
&& `${a.username}@${serverHostLabel(a.serverUrl)}` === id);
|
||||
|
||||
Reference in New Issue
Block a user