mirror of
https://github.com/actualbudget/actual.git
synced 2026-04-30 10:14:53 -05:00
Add session token authentication to API init() (#6540)
* add session token authentication to API init() Allow users to authenticate using a session token directly instead of username/password when initializing the API. This is useful for scenarios where a token has already been obtained through other means. Changes: - Refactor InitConfig to use union types for type-safe auth method selection - Add sessionToken option that validates token on init - Use TypeScript `never` types to make auth methods mutually exclusive * add release notes for session token authentication
This commit is contained in:
@@ -227,13 +227,36 @@ export async function initApp(isDev, socketName) {
|
||||
}
|
||||
}
|
||||
|
||||
export type InitConfig = {
|
||||
type BaseInitConfig = {
|
||||
dataDir?: string;
|
||||
serverURL?: string;
|
||||
password?: string;
|
||||
verbose?: boolean;
|
||||
};
|
||||
|
||||
type ServerInitConfig = BaseInitConfig & {
|
||||
serverURL: string;
|
||||
};
|
||||
|
||||
type PasswordAuthConfig = ServerInitConfig & {
|
||||
password: string;
|
||||
sessionToken?: never;
|
||||
};
|
||||
|
||||
type SessionTokenAuthConfig = ServerInitConfig & {
|
||||
sessionToken: string;
|
||||
password?: never;
|
||||
};
|
||||
|
||||
type NoServerConfig = BaseInitConfig & {
|
||||
serverURL?: undefined;
|
||||
password?: never;
|
||||
sessionToken?: never;
|
||||
};
|
||||
|
||||
export type InitConfig =
|
||||
| PasswordAuthConfig
|
||||
| SessionTokenAuthConfig
|
||||
| NoServerConfig;
|
||||
|
||||
export async function init(config: InitConfig) {
|
||||
// Get from build
|
||||
|
||||
@@ -258,7 +281,26 @@ export async function init(config: InitConfig) {
|
||||
if (serverURL) {
|
||||
setServer(serverURL);
|
||||
|
||||
if (config.password) {
|
||||
if ('sessionToken' in config && config.sessionToken) {
|
||||
// Session token authentication
|
||||
await runHandler(handlers['subscribe-set-token'], {
|
||||
token: config.sessionToken,
|
||||
});
|
||||
// Validate the token
|
||||
const user = await runHandler(handlers['subscribe-get-user'], undefined);
|
||||
if (!user || user.tokenExpired === true) {
|
||||
// Clear invalid token
|
||||
await runHandler(handlers['subscribe-set-token'], { token: '' });
|
||||
throw new Error(
|
||||
'Authentication failed: invalid or expired session token',
|
||||
);
|
||||
}
|
||||
if (user.offline === true) {
|
||||
// Clear token since we can't validate
|
||||
await runHandler(handlers['subscribe-set-token'], { token: '' });
|
||||
throw new Error('Authentication failed: server offline or unreachable');
|
||||
}
|
||||
} else if ('password' in config && config.password) {
|
||||
const result = await runHandler(handlers['subscribe-sign-in'], {
|
||||
password: config.password,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user