1// Copyright (C) 2019 Storj Labs, Inc. 2// See LICENSE for copying information. 3 4import { StoreModule } from '@/store'; 5import { DisableMFARequest, UpdatedUser, User, UsersApi } from '@/types/users'; 6import { MetaUtils } from '@/utils/meta'; 7 8export const USER_ACTIONS = { 9 UPDATE: 'updateUser', 10 GET: 'getUser', 11 ENABLE_USER_MFA: 'enableUserMFA', 12 DISABLE_USER_MFA: 'disableUserMFA', 13 GENERATE_USER_MFA_SECRET: 'generateUserMFASecret', 14 GENERATE_USER_MFA_RECOVERY_CODES: 'generateUserMFARecoveryCodes', 15 CLEAR: 'clearUser', 16}; 17 18export const USER_MUTATIONS = { 19 SET_USER: 'setUser', 20 SET_USER_MFA_SECRET: 'setUserMFASecret', 21 SET_USER_MFA_RECOVERY_CODES: 'setUserMFARecoveryCodes', 22 UPDATE_USER: 'updateUser', 23 CLEAR: 'clearUser', 24}; 25 26export class UsersState { 27 public user: User = new User(); 28 public userMFASecret = ''; 29 public userMFARecoveryCodes: string[] = []; 30} 31 32const { 33 GET, 34 UPDATE, 35 ENABLE_USER_MFA, 36 DISABLE_USER_MFA, 37 GENERATE_USER_MFA_SECRET, 38 GENERATE_USER_MFA_RECOVERY_CODES, 39} = USER_ACTIONS; 40 41const { 42 SET_USER, 43 UPDATE_USER, 44 SET_USER_MFA_SECRET, 45 SET_USER_MFA_RECOVERY_CODES, 46 CLEAR, 47} = USER_MUTATIONS; 48 49interface UsersContext { 50 state: UsersState 51 commit: (string, ...unknown) => void 52} 53 54/** 55 * creates users module with all dependencies 56 * 57 * @param api - users api 58 */ 59export function makeUsersModule(api: UsersApi): StoreModule<UsersState, UsersContext> { 60 return { 61 state: new UsersState(), 62 63 mutations: { 64 [SET_USER](state: UsersState, user: User): void { 65 state.user = user; 66 67 if (user.projectLimit === 0) { 68 const limitFromConfig = MetaUtils.getMetaContent('default-project-limit'); 69 70 state.user.projectLimit = parseInt(limitFromConfig); 71 72 return; 73 } 74 75 state.user.projectLimit = user.projectLimit; 76 }, 77 [CLEAR](state: UsersState): void { 78 state.user = new User(); 79 state.user.projectLimit = 1; 80 }, 81 [UPDATE_USER](state: UsersState, user: UpdatedUser): void { 82 state.user.fullName = user.fullName; 83 state.user.shortName = user.shortName; 84 }, 85 [SET_USER_MFA_SECRET](state: UsersState, secret: string): void { 86 state.userMFASecret = secret; 87 }, 88 [SET_USER_MFA_RECOVERY_CODES](state: UsersState, codes: string[]): void { 89 state.userMFARecoveryCodes = codes; 90 state.user.mfaRecoveryCodeCount = codes.length; 91 }, 92 }, 93 94 actions: { 95 [UPDATE]: async function ({commit}: UsersContext, userInfo: UpdatedUser): Promise<void> { 96 await api.update(userInfo); 97 98 commit(UPDATE_USER, userInfo); 99 }, 100 [GET]: async function ({commit}: UsersContext): Promise<User> { 101 const user = await api.get(); 102 103 commit(SET_USER, user); 104 105 return user; 106 }, 107 [DISABLE_USER_MFA]: async function (_, request: DisableMFARequest): Promise<void> { 108 await api.disableUserMFA(request.passcode, request.recoveryCode); 109 }, 110 [ENABLE_USER_MFA]: async function (_, passcode: string): Promise<void> { 111 await api.enableUserMFA(passcode); 112 }, 113 [GENERATE_USER_MFA_SECRET]: async function ({commit}: UsersContext): Promise<void> { 114 const secret = await api.generateUserMFASecret(); 115 116 commit(SET_USER_MFA_SECRET, secret); 117 }, 118 [GENERATE_USER_MFA_RECOVERY_CODES]: async function ({commit}: UsersContext): Promise<void> { 119 const codes = await api.generateUserMFARecoveryCodes(); 120 121 commit(SET_USER_MFA_RECOVERY_CODES, codes); 122 }, 123 [CLEAR]: function({commit}: UsersContext) { 124 commit(CLEAR); 125 }, 126 }, 127 128 getters: { 129 user: (state: UsersState): User => state.user, 130 userName: (state: UsersState): string => state.user.getFullName(), 131 }, 132 }; 133} 134