From 688d6574b4184900612cc792ff7a03bf10c858a0 Mon Sep 17 00:00:00 2001 From: muntaxir4 Date: Thu, 12 Dec 2024 23:49:54 +0530 Subject: [PATCH 1/7] feat(cli): Add operations for workspace membership --- apps/cli/src/commands/workspace.command.ts | 4 +- .../workspace/membership.workspace.ts | 34 ++++++++++ .../accept-invitation.membership.ts | 49 ++++++++++++++ .../cancel-invitation.membership.ts | 55 ++++++++++++++++ .../decline-invitation.membership.ts | 49 ++++++++++++++ .../membership/get-all-members.membership.ts | 64 ++++++++++++++++++ .../workspace/membership/invite.membership.ts | 65 +++++++++++++++++++ .../workspace/membership/leave.membership.ts | 49 ++++++++++++++ .../workspace/membership/remove.membership.ts | 55 ++++++++++++++++ .../transfer-ownership.membership copy.ts | 55 ++++++++++++++++ .../membership/update-role.membership.ts | 61 +++++++++++++++++ apps/cli/src/util/controller-instance.ts | 15 ++++- 12 files changed, 553 insertions(+), 2 deletions(-) create mode 100644 apps/cli/src/commands/workspace/membership.workspace.ts create mode 100644 apps/cli/src/commands/workspace/membership/accept-invitation.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/cancel-invitation.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/decline-invitation.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/get-all-members.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/invite.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/leave.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/remove.membership.ts create mode 100644 apps/cli/src/commands/workspace/membership/transfer-ownership.membership copy.ts create mode 100644 apps/cli/src/commands/workspace/membership/update-role.membership.ts diff --git a/apps/cli/src/commands/workspace.command.ts b/apps/cli/src/commands/workspace.command.ts index 33b27e26..759356f3 100644 --- a/apps/cli/src/commands/workspace.command.ts +++ b/apps/cli/src/commands/workspace.command.ts @@ -7,6 +7,7 @@ import ListWorkspace from '@/commands/workspace/list.workspace' import SearchWorkspace from '@/commands/workspace/search.workspace' import UpdateWorkspace from '@/commands/workspace/update.workspace' import WorkspaceRoleCommand from '@/commands/workspace/role.workspace' +import WorkspaceMembershipCommand from './workspace/membership.workspace' export default class WorkspaceCommand extends BaseCommand { getName(): string { @@ -26,7 +27,8 @@ export default class WorkspaceCommand extends BaseCommand { new ListWorkspace(), new SearchWorkspace(), new UpdateWorkspace(), - new WorkspaceRoleCommand() + new WorkspaceRoleCommand(), + new WorkspaceMembershipCommand() ] } } diff --git a/apps/cli/src/commands/workspace/membership.workspace.ts b/apps/cli/src/commands/workspace/membership.workspace.ts new file mode 100644 index 00000000..58f3426b --- /dev/null +++ b/apps/cli/src/commands/workspace/membership.workspace.ts @@ -0,0 +1,34 @@ +import BaseCommand from '../base.command' +import AcceptInvitationCommand from './membership/accept-invitation.membership' +import CancelInvitationCommand from './membership/cancel-invitation.membership' +import DeclineInvitationCommand from './membership/decline-invitation.membership' +import GetAllMembersOfWorkspaceCommand from './membership/get-all-members.membership' +import InviteUserCommand from './membership/invite.membership' +import { LeaveWorkspaceCommand } from './membership/leave.membership' +import RemoveUserCommand from './membership/remove.membership' +import TransferOwnershipCommand from './membership/transfer-ownership.membership copy' +import UpdateRolesCommand from './membership/update-role.membership' + +export default class WorkspaceMembershipCommand extends BaseCommand { + getName(): string { + return 'membership' + } + + getDescription(): string { + return 'Manage workspace memberships' + } + + getSubCommands(): BaseCommand[] { + return [ + new AcceptInvitationCommand(), + new CancelInvitationCommand(), + new DeclineInvitationCommand(), + new GetAllMembersOfWorkspaceCommand(), + new InviteUserCommand(), + new LeaveWorkspaceCommand(), + new RemoveUserCommand(), + new TransferOwnershipCommand(), + new UpdateRolesCommand() + ] + } +} diff --git a/apps/cli/src/commands/workspace/membership/accept-invitation.membership.ts b/apps/cli/src/commands/workspace/membership/accept-invitation.membership.ts new file mode 100644 index 00000000..05d895bc --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/accept-invitation.membership.ts @@ -0,0 +1,49 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import ControllerInstance from '@/util/controller-instance' +import { Logger } from '@/util/logger' + +export default class AcceptInvitationCommand extends BaseCommand { + getName(): string { + return 'accept-invitation' + } + + getDescription(): string { + return 'Accept invitation for a workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.acceptInvitation( + { + workspaceSlug + }, + this.headers + ) + + if (success) { + Logger.info('Accepted invitation sucessfully!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + } else { + Logger.error(`Failed to accept invitation: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/cancel-invitation.membership.ts b/apps/cli/src/commands/workspace/membership/cancel-invitation.membership.ts new file mode 100644 index 00000000..a0aa2d95 --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/cancel-invitation.membership.ts @@ -0,0 +1,55 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import { Logger } from '@/util/logger' +import ControllerInstance from '@/util/controller-instance' + +export default class CancelInvitationCommand extends BaseCommand { + getName(): string { + return 'cancel-invitation' + } + + getDescription(): string { + return 'Cancel invitation sent to a user' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + }, + { + name: '', + description: 'Email of the user that was invited.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug, userEmail] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.cancelInvitation( + { + workspaceSlug, + userEmail + }, + this.headers + ) + + if (success) { + Logger.info('Cancelled an invitation for workspace successfully!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + Logger.info(`Invitee: ${userEmail}`) + } else { + Logger.error(`Failed to cancel invitation: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/decline-invitation.membership.ts b/apps/cli/src/commands/workspace/membership/decline-invitation.membership.ts new file mode 100644 index 00000000..602ec420 --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/decline-invitation.membership.ts @@ -0,0 +1,49 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import ControllerInstance from '@/util/controller-instance' +import { Logger } from '@/util/logger' + +export default class DeclineInvitationCommand extends BaseCommand { + getName(): string { + return 'decline-invitation' + } + + getDescription(): string { + return 'Decline invitation of a workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.declineInvitation( + { + workspaceSlug + }, + this.headers + ) + + if (success) { + Logger.info('Declined invitation sucessfully!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + } else { + Logger.error(`Failed to decline invitation: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/get-all-members.membership.ts b/apps/cli/src/commands/workspace/membership/get-all-members.membership.ts new file mode 100644 index 00000000..9666059b --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/get-all-members.membership.ts @@ -0,0 +1,64 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument, + type CommandOption +} from '@/types/command/command.types' +import { Logger } from '@/util/logger' +import ControllerInstance from '@/util/controller-instance' +import { PAGINATION_OPTION } from '@/util/pagination-options' + +export default class GetAllMembersOfWorkspaceCommand extends BaseCommand { + getName(): string { + return 'list' + } + + getDescription(): string { + return 'List all roles of a workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace whose roles you want.' + } + ] + } + + getOptions(): CommandOption[] { + return PAGINATION_OPTION + } + + async action({ args, options }: CommandActionData): Promise { + Logger.info("Fetching workspace's roles...") + + const [workspaceSlug] = args + + const { data, error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.getMembers( + { + workspaceSlug, + ...options + }, + this.headers + ) + + if (success) { + Logger.info('Workspace Members fetched successfully:') + const members = data.items + if (members.length > 0) { + Logger.info('Email\tRole') + members.forEach((member) => { + Logger.info( + `- ${member.user.email} (${member.roles.map((role) => role.role.name).join(', ')})` + ) + }) + } else { + Logger.info('No members found') + } + } else { + Logger.error(`Failed fetching members: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/invite.membership.ts b/apps/cli/src/commands/workspace/membership/invite.membership.ts new file mode 100644 index 00000000..c8807d4d --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/invite.membership.ts @@ -0,0 +1,65 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import { Logger } from '@/util/logger' +import ControllerInstance from '@/util/controller-instance' + +export default class InviteUserCommand extends BaseCommand { + getName(): string { + return 'invite' + } + + getDescription(): string { + return 'Invite a user to a workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + }, + { + name: '', + description: 'Email of the user to invite.' + }, + { + name: '', + description: 'Space-separated list of role slugs to assign to the user.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug, email, ...roleSlugs] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.inviteUsers( + { + workspaceSlug, + members: [ + { + email, + roleSlugs + } + ] + }, + this.headers + ) + + if (success) { + Logger.info('Invited to workspace successfully!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + Logger.info(`Invitee: ${email}`) + Logger.info(`Roles: ${roleSlugs.join(', ')}`) + } else { + Logger.error(`Failed to invite user: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/leave.membership.ts b/apps/cli/src/commands/workspace/membership/leave.membership.ts new file mode 100644 index 00000000..916e0ba3 --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/leave.membership.ts @@ -0,0 +1,49 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import ControllerInstance from '@/util/controller-instance' +import { Logger } from '@/util/logger' + +export class LeaveWorkspaceCommand extends BaseCommand { + getName(): string { + return 'leave' + } + + getDescription(): string { + return 'Leave a workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.leaveWorkspace( + { + workspaceSlug + }, + this.headers + ) + + if (success) { + Logger.info('Left workspace sucessfully!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + } else { + Logger.error(`Failed to leave workspace: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/remove.membership.ts b/apps/cli/src/commands/workspace/membership/remove.membership.ts new file mode 100644 index 00000000..5a94d1e4 --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/remove.membership.ts @@ -0,0 +1,55 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import ControllerInstance from '@/util/controller-instance' +import { Logger } from '@/util/logger' + +export default class RemoveUserCommand extends BaseCommand { + getName(): string { + return 'remove' + } + + getDescription(): string { + return 'Remove a user from a workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + }, + { + name: '', + description: 'Email of the user to remove.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug, email] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.removeUsers( + { + workspaceSlug, + userEmails: email + }, + this.headers + ) + + if (success) { + Logger.info('Removed user from workspace successfully!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + Logger.info(`User email: ${email}`) + } else { + Logger.error(`Failed to remove user: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/transfer-ownership.membership copy.ts b/apps/cli/src/commands/workspace/membership/transfer-ownership.membership copy.ts new file mode 100644 index 00000000..e140c5ff --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/transfer-ownership.membership copy.ts @@ -0,0 +1,55 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import { Logger } from '@/util/logger' +import ControllerInstance from '@/util/controller-instance' + +export default class TransferOwnershipCommand extends BaseCommand { + getName(): string { + return 'transfer-ownership' + } + + getDescription(): string { + return 'Transfer the ownership of the workspace to another user ' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + }, + { + name: '', + description: 'Email of the new owner of the workspace.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug, newOwnerEmail] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.transferOwnership( + { + workspaceSlug, + userEmail: newOwnerEmail + }, + this.headers + ) + + if (success) { + Logger.info('Workspace Ownership transferred successfully!') + Logger.info(`New owner email: ${newOwnerEmail}`) + Logger.info(`Workspace slug: ${workspaceSlug}`) + } else { + Logger.error(`Failed to transfer ownership: ${error.message}`) + } + } +} diff --git a/apps/cli/src/commands/workspace/membership/update-role.membership.ts b/apps/cli/src/commands/workspace/membership/update-role.membership.ts new file mode 100644 index 00000000..a8d60d29 --- /dev/null +++ b/apps/cli/src/commands/workspace/membership/update-role.membership.ts @@ -0,0 +1,61 @@ +import BaseCommand from '@/commands/base.command' +import { + type CommandActionData, + type CommandArgument +} from '@/types/command/command.types' +import { Logger } from '@/util/logger' +import ControllerInstance from '@/util/controller-instance' + +export default class UpdateRolesCommand extends BaseCommand { + getName(): string { + return 'update-role' + } + + getDescription(): string { + return 'Update roles of a user in workspace' + } + + getArguments(): CommandArgument[] { + return [ + { + name: '', + description: 'Slug of the workspace which you want to fetch.' + }, + { + name: '', + description: 'Email of the workspace member.' + }, + { + name: '', + description: 'Space-separated list of role slugs to assign to the user.' + } + ] + } + + canMakeHttpRequests(): boolean { + return true + } + + async action({ args }: CommandActionData): Promise { + const [workspaceSlug, userEmail, ...roleSlugs] = args + + const { error, success } = + await ControllerInstance.getInstance().workspaceMembershipController.updateMemberRoles( + { + workspaceSlug, + userEmail, + roleSlugs + }, + this.headers + ) + + if (success) { + Logger.info('Updated the roles of user!') + Logger.info(`Workspace slug: ${workspaceSlug}`) + Logger.info(`Member Email: ${userEmail}`) + Logger.info(`New Roles: ${roleSlugs.join(', ')}`) + } else { + Logger.error(`Failed to update roles: ${error.message}`) + } + } +} diff --git a/apps/cli/src/util/controller-instance.ts b/apps/cli/src/util/controller-instance.ts index bc6b2e59..0fd5d37b 100644 --- a/apps/cli/src/util/controller-instance.ts +++ b/apps/cli/src/util/controller-instance.ts @@ -6,7 +6,8 @@ import { SecretController, VariableController, WorkspaceController, - WorkspaceRoleController + WorkspaceRoleController, + WorkspaceMembershipController } from '@keyshade/api-client' export default class ControllerInstance { @@ -84,6 +85,16 @@ export default class ControllerInstance { return this._workspaceRoleController } + private _workspaceMembershipController: WorkspaceMembershipController | null = + null + + get workspaceMembershipController(): WorkspaceMembershipController { + if (!this._workspaceMembershipController) { + throw new Error('ControllerInstance not initialized') + } + return this._workspaceMembershipController + } + static initialize(baseUrl: string) { if (!ControllerInstance.instance) { const instance = new ControllerInstance() @@ -96,6 +107,8 @@ export default class ControllerInstance { instance._variableController = new VariableController(baseUrl) instance._workspaceController = new WorkspaceController(baseUrl) instance._workspaceRoleController = new WorkspaceRoleController(baseUrl) + instance._workspaceMembershipController = + new WorkspaceMembershipController(baseUrl) ControllerInstance.instance = instance } From e0a0d9a9b6c6ee1ebe282210714c601a4d334cea Mon Sep 17 00:00:00 2001 From: muntaxir4 Date: Fri, 13 Dec 2024 00:48:26 +0530 Subject: [PATCH 2/7] fix(cli): Update role slugs handling as variadic argument --- .../commands/workspace/membership/invite.membership.ts | 10 +++++----- .../workspace/membership/update-role.membership.ts | 8 ++++---- apps/cli/src/commands/workspace/role/update.role.ts | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/cli/src/commands/workspace/membership/invite.membership.ts b/apps/cli/src/commands/workspace/membership/invite.membership.ts index c8807d4d..f49960e9 100644 --- a/apps/cli/src/commands/workspace/membership/invite.membership.ts +++ b/apps/cli/src/commands/workspace/membership/invite.membership.ts @@ -26,7 +26,7 @@ export default class InviteUserCommand extends BaseCommand { description: 'Email of the user to invite.' }, { - name: '', + name: '', description: 'Space-separated list of role slugs to assign to the user.' } ] @@ -36,8 +36,8 @@ export default class InviteUserCommand extends BaseCommand { return true } - async action({ args }: CommandActionData): Promise { - const [workspaceSlug, email, ...roleSlugs] = args + async action({ args, options }: CommandActionData): Promise { + const [workspaceSlug, email, roleSlugs] = args const { error, success } = await ControllerInstance.getInstance().workspaceMembershipController.inviteUsers( @@ -46,7 +46,7 @@ export default class InviteUserCommand extends BaseCommand { members: [ { email, - roleSlugs + roleSlugs: roleSlugs.split(',') } ] }, @@ -57,7 +57,7 @@ export default class InviteUserCommand extends BaseCommand { Logger.info('Invited to workspace successfully!') Logger.info(`Workspace slug: ${workspaceSlug}`) Logger.info(`Invitee: ${email}`) - Logger.info(`Roles: ${roleSlugs.join(', ')}`) + Logger.info(`Roles: ${roleSlugs}`) } else { Logger.error(`Failed to invite user: ${error.message}`) } diff --git a/apps/cli/src/commands/workspace/membership/update-role.membership.ts b/apps/cli/src/commands/workspace/membership/update-role.membership.ts index a8d60d29..9334cd97 100644 --- a/apps/cli/src/commands/workspace/membership/update-role.membership.ts +++ b/apps/cli/src/commands/workspace/membership/update-role.membership.ts @@ -26,7 +26,7 @@ export default class UpdateRolesCommand extends BaseCommand { description: 'Email of the workspace member.' }, { - name: '', + name: '', description: 'Space-separated list of role slugs to assign to the user.' } ] @@ -37,14 +37,14 @@ export default class UpdateRolesCommand extends BaseCommand { } async action({ args }: CommandActionData): Promise { - const [workspaceSlug, userEmail, ...roleSlugs] = args + const [workspaceSlug, userEmail, roleSlugs] = args const { error, success } = await ControllerInstance.getInstance().workspaceMembershipController.updateMemberRoles( { workspaceSlug, userEmail, - roleSlugs + roleSlugs: roleSlugs.split(',') }, this.headers ) @@ -53,7 +53,7 @@ export default class UpdateRolesCommand extends BaseCommand { Logger.info('Updated the roles of user!') Logger.info(`Workspace slug: ${workspaceSlug}`) Logger.info(`Member Email: ${userEmail}`) - Logger.info(`New Roles: ${roleSlugs.join(', ')}`) + Logger.info(`New Roles: ${roleSlugs}`) } else { Logger.error(`Failed to update roles: ${error.message}`) } diff --git a/apps/cli/src/commands/workspace/role/update.role.ts b/apps/cli/src/commands/workspace/role/update.role.ts index c78f6d84..cb6a01fa 100644 --- a/apps/cli/src/commands/workspace/role/update.role.ts +++ b/apps/cli/src/commands/workspace/role/update.role.ts @@ -44,12 +44,12 @@ export default class UpdateRoleCommand extends BaseCommand { }, { short: '-a', - long: '--authorities ', + long: '--authorities ', description: 'Authorities of the workspace role.' }, { short: '-p', - long: '--project-slugs ', + long: '--project-slugs ', description: 'Project slugs of the workspace role.' } ] From 19c5371b93ad907d87f1d9db922a29d0428fe7d2 Mon Sep 17 00:00:00 2001 From: muntaxir4 Date: Fri, 13 Dec 2024 00:50:03 +0530 Subject: [PATCH 3/7] fix(api): Improve formatting using lint --- apps/api/src/environment/environment.e2e.spec.ts | 2 +- .../emails/components/base-email-template.tsx | 12 ++++++------ apps/api/src/mail/emails/workspace-invitation.tsx | 15 ++++++--------- apps/api/src/mail/emails/workspace-removal.tsx | 6 +++--- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/apps/api/src/environment/environment.e2e.spec.ts b/apps/api/src/environment/environment.e2e.spec.ts index ad949f1c..c42ea77b 100644 --- a/apps/api/src/environment/environment.e2e.spec.ts +++ b/apps/api/src/environment/environment.e2e.spec.ts @@ -184,7 +184,7 @@ describe('Environment Controller Tests', () => { 'x-e2e-user-email': user1.email } }) - + expect(response.statusCode).toBe(400) expect(response.json().message).toContain('name should not be empty') }) diff --git a/apps/api/src/mail/emails/components/base-email-template.tsx b/apps/api/src/mail/emails/components/base-email-template.tsx index 891ddfe0..07dcf422 100644 --- a/apps/api/src/mail/emails/components/base-email-template.tsx +++ b/apps/api/src/mail/emails/components/base-email-template.tsx @@ -42,13 +42,13 @@ export const BaseEmailTemplate: React.FC = ({ {heading} {children} - If you believe this action was taken in error or have any - questions regarding this change, please contact your project - administrator or our support team. + If you believe this action was taken in error or have any + questions regarding this change, please contact your project + administrator or our support team. - We appreciate your understanding and thank you for your - contributions to the project. + We appreciate your understanding and thank you for your + contributions to the project. Cheers, @@ -81,4 +81,4 @@ export const BaseEmailTemplate: React.FC = ({ ) } -export default BaseEmailTemplate \ No newline at end of file +export default BaseEmailTemplate diff --git a/apps/api/src/mail/emails/workspace-invitation.tsx b/apps/api/src/mail/emails/workspace-invitation.tsx index 37b4fc0f..5fab5df7 100644 --- a/apps/api/src/mail/emails/workspace-invitation.tsx +++ b/apps/api/src/mail/emails/workspace-invitation.tsx @@ -33,14 +33,11 @@ export const WorkspaceInvitationEmail = ({ : 'You are Invited to Join the Workspace' return ( - + Dear User, - We're excited to inform you that you've been invited to join a - workspace on Keyshade. Here are the details of your invitation: + We're excited to inform you that you've been invited to join a workspace + on Keyshade. Here are the details of your invitation:
@@ -54,8 +51,8 @@ export const WorkspaceInvitationEmail = ({
- Join the project by clicking the button below - we're excited to - have you! + Join the project by clicking the button below - we're excited to have + you!