1 import type { Api, ApiAuth } from '@proton/pass/types';
2 import { partition } from '@proton/pass/utils/array/partition';
3 import { revoke } from '@proton/shared/lib/api/auth';
4 import noop from '@proton/utils/noop';
6 import { getActiveSessions } from './session';
8 export type SwitchableSession = {
9 /** Fallsback to `Username` if address `DisplayName` is not set */
18 type AuthSwitchConfig = {
20 onSwitch: (LocalID: number) => void;
21 getSessions: () => SwitchableSession[];
22 onActiveSession: (session: SwitchableSession) => void;
23 onInactiveSession: (session: SwitchableSession) => void;
24 onSessionsSynced: (sessions: SwitchableSession[]) => void;
27 export const createAuthSwitchService = (config: AuthSwitchConfig) => {
28 const { api } = config;
31 /** Revoke may be called on a session different then
32 * what the authentication store is actually configured
33 * with : as such, pass the `UID` to the revoke call.
34 * The API call is flagged as side-effects free to avoid
35 * mutating the API state of the current active session. */
36 revoke: (auth: ApiAuth) => {
37 api({ ...revoke(), sideEffects: false, auth }).catch(noop);
38 const localSessions = config.getSessions();
39 const revoked = localSessions.find((session) => session.UID === auth.UID);
40 if (revoked) config.onInactiveSession(revoked);
43 switch: config.onSwitch,
45 sync: async (options: { revalidate: boolean }): Promise<SwitchableSession[]> => {
46 const localSessions = config.getSessions();
47 const activeSessions = options.revalidate ? await getActiveSessions(api) : null;
49 if (!activeSessions) {
50 config.onSessionsSynced(localSessions);
54 const sessions = new Map(activeSessions.map((session) => [session.LocalID, session]));
55 const [localActive, inactive] = partition(localSessions, ({ LocalID }) => sessions.has(LocalID!));
57 const active = localActive.map((session) => {
58 const { DisplayName, Username, PrimaryEmail = '' } = sessions.get(session.LocalID)!;
61 /** Fallback to `Username` if no `DisplayName` set
62 * for the session's email address */
63 DisplayName: DisplayName ?? Username,
68 active.forEach(config.onActiveSession);
69 inactive.forEach(config.onInactiveSession);
71 config.onSessionsSynced(active);
78 export type AuthSwitchService = ReturnType<typeof createAuthSwitchService>;