| @@ -92,5 +92,19 @@ namespace api { | |||||||
|     void admin::is_admin(req_type, cbk_type cbk) { |     void admin::is_admin(req_type, cbk_type cbk) { | ||||||
|         cbk(dto::Responses::get_success_res()); |         cbk(dto::Responses::get_success_res()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void admin::get_token(req_type, cbk_type cbk, uint64_t user) { | ||||||
|  |         db::MapperUser user_mapper(drogon::app().getDbClient()); | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             const auto &db_user = user_mapper.findByPrimaryKey(user); | ||||||
|  |  | ||||||
|  |             const std::string &token = auth::get_token(db_user); | ||||||
|  |  | ||||||
|  |             cbk(dto::Responses::get_login_res(token)); | ||||||
|  |         } catch (const std::exception&) { | ||||||
|  |             cbk(dto::Responses::get_badreq_res("Bad user")); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| #pragma clang diagnostic pop | #pragma clang diagnostic pop | ||||||
| @@ -25,6 +25,7 @@ public: | |||||||
|         METHOD_ADD(admin::delete_user, "/delete", drogon::Post, "Login", "Admin"); |         METHOD_ADD(admin::delete_user, "/delete", drogon::Post, "Login", "Admin"); | ||||||
|         METHOD_ADD(admin::disable_2fa, "/disable_2fa", drogon::Post, "Login", "Admin"); |         METHOD_ADD(admin::disable_2fa, "/disable_2fa", drogon::Post, "Login", "Admin"); | ||||||
|         METHOD_ADD(admin::is_admin, "/is_admin", drogon::Get, "Login", "Admin"); |         METHOD_ADD(admin::is_admin, "/is_admin", drogon::Get, "Login", "Admin"); | ||||||
|  |         METHOD_ADD(admin::get_token, "/get_token/{}", drogon::Get, "Login", "Admin"); | ||||||
|     METHOD_LIST_END |     METHOD_LIST_END | ||||||
|  |  | ||||||
|     void users(req_type, cbk_type); |     void users(req_type, cbk_type); | ||||||
| @@ -33,6 +34,7 @@ public: | |||||||
|     void delete_user(req_type, cbk_type); |     void delete_user(req_type, cbk_type); | ||||||
|     void disable_2fa(req_type, cbk_type); |     void disable_2fa(req_type, cbk_type); | ||||||
|     void is_admin(req_type, cbk_type); |     void is_admin(req_type, cbk_type); | ||||||
|  |     void get_token(req_type, cbk_type, uint64_t user); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class auth : public drogon::HttpController<auth> { | class auth : public drogon::HttpController<auth> { | ||||||
|   | |||||||
| @@ -54,5 +54,11 @@ export const disable_tfa = ( | |||||||
| 		token | 		token | ||||||
| 	); | 	); | ||||||
|  |  | ||||||
|  | export const impersonate = ( | ||||||
|  | 	user: number, | ||||||
|  | 	token: string | ||||||
|  | ): Promise<Responses.Login | Responses.Error> => | ||||||
|  | 	get_token(`/api/admin/get_token/${user}`, token); | ||||||
|  |  | ||||||
| export const is_admin = async (token: string): Promise<boolean> => | export const is_admin = async (token: string): Promise<boolean> => | ||||||
| 	!isErrorResponse(await get_token('/api/admin/is_admin', token)); | 	!isErrorResponse(await get_token('/api/admin/is_admin', token)); | ||||||
|   | |||||||
| @@ -48,6 +48,16 @@ const setRole = loadingMsgWrapper( | |||||||
| 	} | 	} | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | const impersonate = loadingMsgWrapper(message, async (user: number) => { | ||||||
|  | 	const token = await check_token(jwt); | ||||||
|  | 	if (!token) return; | ||||||
|  |  | ||||||
|  | 	const res = await Admin.impersonate(user, token); | ||||||
|  | 	if (isErrorResponse(res)) return console.error(res.message); | ||||||
|  | 	jwt.setToken(res.jwt); | ||||||
|  | 	await router.push({ path: '/' }); | ||||||
|  | }); | ||||||
|  |  | ||||||
| const action = ( | const action = ( | ||||||
| 	func: ( | 	func: ( | ||||||
| 		user: number, | 		user: number, | ||||||
| @@ -122,6 +132,9 @@ const columns: DataTableColumn<Responses.GetUsersEntry>[] = [ | |||||||
| 		render(user) { | 		render(user) { | ||||||
| 			return ( | 			return ( | ||||||
| 				<NButtonGroup> | 				<NButtonGroup> | ||||||
|  | 					<NButton onClick={() => impersonate(user.id)}> | ||||||
|  | 						Impersonate | ||||||
|  | 					</NButton> | ||||||
| 					<NButton onClick={() => logoutUser(user.id)}> | 					<NButton onClick={() => logoutUser(user.id)}> | ||||||
| 						Logout all | 						Logout all | ||||||
| 					</NButton> | 					</NButton> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user