mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-06 00:07:44 +01:00
7d73d772df
https://linear.app/unleash/issue/2-579/improve-user-like-behaviour-for-service-accounts-accounts-concept Builds on top of https://github.com/Unleash/unleash/pull/2917 by moving the responsibility of handling both account types from `users` to `accounts`. Ideally: - `users` - Should only handle users; - `service-accounts` - Should only handle service accounts; - `accounts` - Should handle any type of account; This should hopefully also provide a good building block in case we later decide to refactor this further down the `accounts` path.
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import { Logger } from '../logger';
|
|
import { IUser } from '../types/user';
|
|
import { IUnleashConfig } from '../types/option';
|
|
import { IAccountStore, IUnleashStores } from '../types/stores';
|
|
import { minutesToMilliseconds } from 'date-fns';
|
|
import { AccessService } from './access-service';
|
|
import { RoleName } from '../types/model';
|
|
|
|
interface IUserWithRole extends IUser {
|
|
rootRole: number;
|
|
}
|
|
|
|
export class AccountService {
|
|
private logger: Logger;
|
|
|
|
private store: IAccountStore;
|
|
|
|
private accessService: AccessService;
|
|
|
|
private seenTimer: NodeJS.Timeout;
|
|
|
|
private lastSeenSecrets: Set<string> = new Set<string>();
|
|
|
|
constructor(
|
|
stores: Pick<IUnleashStores, 'accountStore' | 'eventStore'>,
|
|
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
|
|
services: {
|
|
accessService: AccessService;
|
|
},
|
|
) {
|
|
this.logger = getLogger('service/account-service.ts');
|
|
this.store = stores.accountStore;
|
|
this.accessService = services.accessService;
|
|
this.updateLastSeen();
|
|
}
|
|
|
|
async getAll(): Promise<IUserWithRole[]> {
|
|
const accounts = await this.store.getAll();
|
|
const defaultRole = await this.accessService.getRootRole(
|
|
RoleName.VIEWER,
|
|
);
|
|
const userRoles = await this.accessService.getRootRoleForAllUsers();
|
|
const accountsWithRootRole = accounts.map((u) => {
|
|
const rootRole = userRoles.find((r) => r.userId === u.id);
|
|
const roleId = rootRole ? rootRole.roleId : defaultRole.id;
|
|
return { ...u, rootRole: roleId };
|
|
});
|
|
return accountsWithRootRole;
|
|
}
|
|
|
|
async getAccountByPersonalAccessToken(secret: string): Promise<IUser> {
|
|
return this.store.getAccountByPersonalAccessToken(secret);
|
|
}
|
|
|
|
async updateLastSeen(): Promise<void> {
|
|
if (this.lastSeenSecrets.size > 0) {
|
|
const toStore = [...this.lastSeenSecrets];
|
|
this.lastSeenSecrets = new Set<string>();
|
|
await this.store.markSeenAt(toStore);
|
|
}
|
|
|
|
this.seenTimer = setTimeout(
|
|
async () => this.updateLastSeen(),
|
|
minutesToMilliseconds(3),
|
|
).unref();
|
|
}
|
|
|
|
addPATSeen(secret: string): void {
|
|
this.lastSeenSecrets.add(secret);
|
|
}
|
|
|
|
destroy(): void {
|
|
clearTimeout(this.seenTimer);
|
|
this.seenTimer = null;
|
|
}
|
|
}
|