382 lines
9.7 KiB
TypeScript
382 lines
9.7 KiB
TypeScript
'use server';
|
|
|
|
import { revalidatePath } from 'next/cache';
|
|
import { redirect } from 'next/navigation';
|
|
|
|
import { enhanceAction } from '@kit/next/actions';
|
|
import { getLogger } from '@kit/shared/logger';
|
|
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
|
|
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
|
|
|
import {
|
|
BanUserSchema,
|
|
DeleteAccountSchema,
|
|
DeleteUserSchema,
|
|
ImpersonateUserSchema,
|
|
ReactivateUserSchema,
|
|
UpdateAccountRoleSchema,
|
|
} from './schema/admin-actions.schema';
|
|
import { CreateCompanySchema } from './schema/create-company.schema';
|
|
import { CreateUserSchema } from './schema/create-user.schema';
|
|
import { ResetPasswordSchema } from './schema/reset-password.schema';
|
|
import { createAdminAccountsService } from './services/admin-accounts.service';
|
|
import { createAdminAuthUserService } from './services/admin-auth-user.service';
|
|
import { createCreateCompanyAccountService } from './services/admin-create-company-account.service';
|
|
import { adminAction } from './utils/admin-action';
|
|
import { getAdminSdk } from './utils/medusa-sdk';
|
|
|
|
/**
|
|
* @name banUserAction
|
|
* @description Ban a user from the system.
|
|
*/
|
|
export const banUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is banning user...`);
|
|
|
|
await service.banUser(userId);
|
|
|
|
logger.info({ userId }, `Super Admin has successfully banned user`);
|
|
|
|
revalidateAdmin();
|
|
|
|
return {
|
|
success: true,
|
|
};
|
|
},
|
|
{
|
|
schema: BanUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name reactivateUserAction
|
|
* @description Reactivate a user in the system.
|
|
*/
|
|
export const reactivateUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is reactivating user...`);
|
|
|
|
await service.reactivateUser(userId);
|
|
|
|
logger.info({ userId }, `Super Admin has successfully reactivated user`);
|
|
|
|
revalidateAdmin();
|
|
|
|
return {
|
|
success: true,
|
|
};
|
|
},
|
|
{
|
|
schema: ReactivateUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name impersonateUserAction
|
|
* @description Impersonate a user in the system.
|
|
*/
|
|
export const impersonateUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is impersonating user...`);
|
|
|
|
return await service.impersonateUser(userId);
|
|
},
|
|
{
|
|
schema: ImpersonateUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name deleteUserAction
|
|
* @description Delete a user from the system.
|
|
*/
|
|
export const deleteUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is deleting user...`);
|
|
|
|
await service.deleteUser(userId);
|
|
|
|
logger.info({ userId }, `Super Admin has successfully deleted user`);
|
|
|
|
revalidateAdmin();
|
|
|
|
return redirect('/admin/accounts');
|
|
},
|
|
{
|
|
schema: DeleteUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name deleteAccountAction
|
|
* @description Delete an account from the system.
|
|
*/
|
|
export const deleteAccountAction = adminAction(
|
|
enhanceAction(
|
|
async ({ accountId }) => {
|
|
const service = getAdminAccountsService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ accountId }, `Super Admin is deleting account...`);
|
|
|
|
const { name: customerGroupName } = await service.getAccount(accountId);
|
|
try {
|
|
await service.deleteAccount(accountId);
|
|
} catch (e) {
|
|
logger.error({ accountId }, `Error deleting company account`);
|
|
throw e;
|
|
}
|
|
const medusa = getAdminSdk();
|
|
const { customer_groups } = await medusa.admin.customerGroup.list();
|
|
const customerGroup = customer_groups.find(
|
|
({ name }) => name === customerGroupName,
|
|
);
|
|
if (customerGroup) {
|
|
try {
|
|
await medusa.admin.customerGroup.delete(customerGroup.id);
|
|
} catch (e) {
|
|
logger.error(
|
|
{ accountId },
|
|
`Error deleting Medusa customer group for company ${customerGroupName}`,
|
|
);
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
logger.info(
|
|
{ accountId },
|
|
`Super Admin has successfully deleted account`,
|
|
);
|
|
|
|
revalidateAdmin();
|
|
|
|
return redirect('/admin/accounts');
|
|
},
|
|
{
|
|
schema: DeleteAccountSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name createUserAction
|
|
* @description Create a new user in the system.
|
|
*/
|
|
export const createUserAction = adminAction(
|
|
enhanceAction(
|
|
async ({ email, password, emailConfirm, personalCode }) => {
|
|
const adminClient = getSupabaseServerAdminClient();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ email }, `Super Admin is creating a new user...`);
|
|
|
|
const { data, error } = await adminClient.auth.admin.createUser({
|
|
email,
|
|
password,
|
|
email_confirm: emailConfirm,
|
|
});
|
|
|
|
if (error) {
|
|
logger.error({ error }, `Error creating user`);
|
|
throw new Error(`Error creating user: ${error.message}`);
|
|
}
|
|
|
|
logger.info(
|
|
{ userId: data.user.id },
|
|
`Super Admin has successfully created a new user`,
|
|
);
|
|
|
|
const { error: accountError } = await adminClient
|
|
.schema('medreport')
|
|
.from('accounts')
|
|
.update({ personal_code: personalCode })
|
|
.eq('id', data.user.id);
|
|
|
|
if (accountError) {
|
|
logger.error(
|
|
{ accountError },
|
|
'Error inserting personal code to accounts',
|
|
);
|
|
throw new Error(`Error saving personal code: ${accountError.message}`);
|
|
}
|
|
|
|
revalidateAdmin();
|
|
|
|
return {
|
|
success: true,
|
|
user: data.user,
|
|
};
|
|
},
|
|
{
|
|
schema: CreateUserSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @name resetPasswordAction
|
|
* @description Reset a user's password by sending a password reset email.
|
|
*/
|
|
export const resetPasswordAction = adminAction(
|
|
enhanceAction(
|
|
async ({ userId }) => {
|
|
const service = getAdminAuthService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ userId }, `Super Admin is resetting user password...`);
|
|
|
|
const result = await service.resetPassword(userId);
|
|
|
|
logger.info(
|
|
{ userId },
|
|
`Super Admin has successfully sent password reset email`,
|
|
);
|
|
|
|
revalidateAdmin();
|
|
|
|
return result;
|
|
},
|
|
{
|
|
schema: ResetPasswordSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
export const createCompanyAccountAction = enhanceAction(
|
|
async ({ name, ownerPersonalCode }, user) => {
|
|
const logger = await getLogger();
|
|
const client = getSupabaseServerClient();
|
|
const service = createCreateCompanyAccountService(client);
|
|
|
|
const ctx = {
|
|
name: 'team-accounts.create',
|
|
userId: user.id,
|
|
accountName: name,
|
|
};
|
|
|
|
logger.info(ctx, `Creating company account...`);
|
|
|
|
const { data, error } = await service.createNewOrganizationAccount({
|
|
name,
|
|
ownerPersonalCode,
|
|
});
|
|
|
|
if (error) {
|
|
logger.error({ ...ctx, error }, `Failed to create company account`);
|
|
|
|
return {
|
|
error: true,
|
|
};
|
|
}
|
|
|
|
logger.info(ctx, `Company account created`);
|
|
|
|
logger.info(ctx, `Creating Medusa customer group`);
|
|
const medusa = getAdminSdk();
|
|
const { customer_groups: existingCustomerGroups } =
|
|
await medusa.admin.customerGroup.list();
|
|
const isExisting = existingCustomerGroups.find(
|
|
(group) => group.name === name,
|
|
);
|
|
if (isExisting) {
|
|
logger.info(ctx, `Customer group already exists`);
|
|
} else {
|
|
logger.info(ctx, `Creating Medusa customer group`);
|
|
const { data: account } = await client
|
|
.schema('medreport')
|
|
.from('accounts')
|
|
.select('medusa_account_id')
|
|
.eq('personal_code', ownerPersonalCode)
|
|
.single()
|
|
.throwOnError();
|
|
const medusaAccountId = account.medusa_account_id;
|
|
if (!medusaAccountId) {
|
|
logger.error(ctx, `User has no Medusa account ID`);
|
|
} else {
|
|
const {
|
|
customer_group: { id: customerGroupId },
|
|
} = await medusa.admin.customerGroup.create({ name });
|
|
const { customers } = await medusa.admin.customer.list({
|
|
id: medusaAccountId,
|
|
});
|
|
if (customers.length !== 1) {
|
|
logger.error(ctx, `Customer not found`);
|
|
} else {
|
|
const customerId = customers[0]!.id;
|
|
await medusa.admin.customer.batchCustomerGroups(customerId, {
|
|
add: [customerGroupId],
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
redirect(`/admin/accounts/${data.id}`);
|
|
},
|
|
{
|
|
schema: CreateCompanySchema,
|
|
},
|
|
);
|
|
|
|
/**
|
|
* @name updateRoleAction
|
|
* @description Update application role for user
|
|
*/
|
|
export const updateRoleAction = adminAction(
|
|
enhanceAction(
|
|
async ({ accountId, role }) => {
|
|
const service = getAdminAccountsService();
|
|
const logger = await getLogger();
|
|
|
|
logger.info({ accountId }, `Super Admin is updating account role...`);
|
|
|
|
await service.updateRole(accountId, role);
|
|
|
|
logger.info({ accountId }, `Successfully changed role`);
|
|
|
|
revalidateAdmin();
|
|
|
|
return { success: true };
|
|
},
|
|
{
|
|
schema: UpdateAccountRoleSchema,
|
|
},
|
|
),
|
|
);
|
|
|
|
function revalidateAdmin() {
|
|
revalidatePath('/admin', 'layout');
|
|
}
|
|
|
|
function getAdminAuthService() {
|
|
const client = getSupabaseServerClient();
|
|
const adminClient = getSupabaseServerAdminClient();
|
|
|
|
return createAdminAuthUserService(client, adminClient);
|
|
}
|
|
|
|
function getAdminAccountsService() {
|
|
const adminClient = getSupabaseServerAdminClient();
|
|
|
|
return createAdminAccountsService(adminClient);
|
|
}
|