Delete userWorkspace when removed from workspace (#13131)

Fixes https://github.com/twentyhq/twenty/issues/13024
This commit is contained in:
Charles Bochet
2025-07-09 18:34:50 +02:00
committed by GitHub
parent eba997be98
commit 7e419337b5
71 changed files with 377 additions and 436 deletions

View File

@ -5,11 +5,12 @@ declare module '@jest/types' {
namespace Config { namespace Config {
interface ConfigGlobals { interface ConfigGlobals {
APP_PORT: number; APP_PORT: number;
ADMIN_ACCESS_TOKEN: string; APPLE_JANE_ADMIN_ACCESS_TOKEN: string;
EXPIRED_ACCESS_TOKEN: string; EXPIRED_ACCESS_TOKEN: string;
INVALID_ACCESS_TOKEN: string; INVALID_ACCESS_TOKEN: string;
MEMBER_ACCESS_TOKEN: string; APPLE_JONY_MEMBER_ACCESS_TOKEN: string;
GUEST_ACCESS_TOKEN: string; APPLE_PHIL_GUEST_ACCESS_TOKEN: string;
ACME_JONY_MEMBER_ACCESS_TOKEN: string;
API_KEY_ACCESS_TOKEN: string; API_KEY_ACCESS_TOKEN: string;
testDataSource?: DataSource; testDataSource?: DataSource;
} }
@ -18,12 +19,13 @@ declare module '@jest/types' {
declare global { declare global {
const APP_PORT: number; const APP_PORT: number;
const ADMIN_ACCESS_TOKEN: string; const APPLE_JANE_ADMIN_ACCESS_TOKEN: string;
const EXPIRED_ACCESS_TOKEN: string; const EXPIRED_ACCESS_TOKEN: string;
const INVALID_ACCESS_TOKEN: string; const INVALID_ACCESS_TOKEN: string;
const MEMBER_ACCESS_TOKEN: string; const APPLE_JONY_MEMBER_ACCESS_TOKEN: string;
const GUEST_ACCESS_TOKEN: string; const APPLE_PHIL_GUEST_ACCESS_TOKEN: string;
const API_KEY_ACCESS_TOKEN: string; const API_KEY_ACCESS_TOKEN: string;
const ACME_JONY_MEMBER_ACCESS_TOKEN: string;
const WORKSPACE_AGNOSTIC_TOKEN: string; const WORKSPACE_AGNOSTIC_TOKEN: string;
const testDataSource: DataSource; const testDataSource: DataSource;
} }

View File

@ -74,16 +74,18 @@ const jestConfig: JestConfigWithTsJest = {
globals: { globals: {
APP_PORT: 4000, APP_PORT: 4000,
NODE_ENV: NodeEnvironment.TEST, NODE_ENV: NodeEnvironment.TEST,
ADMIN_ACCESS_TOKEN: APPLE_JANE_ADMIN_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ1c2VySWQiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNDYzZi00MzViLTgyOGMtMTA3ZTAwN2EyNzExIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWU3Yy00M2Q5LWE1ZGItNjg1YjUwNjlkODE2IiwidHlwZSI6IkFDQ0VTUyIsImF1dGhQcm92aWRlciI6InBhc3N3b3JkIiwiaWF0IjoxNzUxMjgxNzA0LCJleHAiOjIwNjY4NTc3MDR9.HMGqCsVlOAPVUBhKSGlD1X86VoHKt4LIUtET3CGIdik', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ1c2VySWQiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNDYzZi00MzViLTgyOGMtMTA3ZTAwN2EyNzExIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWU3Yy00M2Q5LWE1ZGItNjg1YjUwNjlkODE2IiwidHlwZSI6IkFDQ0VTUyIsImF1dGhQcm92aWRlciI6InBhc3N3b3JkIiwiaWF0IjoxNzUxMjgxNzA0LCJleHAiOjIwNjY4NTc3MDR9.HMGqCsVlOAPVUBhKSGlD1X86VoHKt4LIUtET3CGIdik',
EXPIRED_ACCESS_TOKEN: EXPIRED_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC05ZTNiLTQ2ZDQtYTU1Ni04OGI5ZGRjMmIwMzQiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMDY4Ny00YzQxLWI3MDctZWQxYmZjYTk3MmE3IiwiaWF0IjoxNzM4MzIzODc5LCJleHAiOjE3MzgzMjU2Nzl9.m73hHVpnw5uGNGrSuKxn6XtKEUK3Wqkp4HsQdYfZiHo', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC05ZTNiLTQ2ZDQtYTU1Ni04OGI5ZGRjMmIwMzQiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMDY4Ny00YzQxLWI3MDctZWQxYmZjYTk3MmE3IiwiaWF0IjoxNzM4MzIzODc5LCJleHAiOjE3MzgzMjU2Nzl9.m73hHVpnw5uGNGrSuKxn6XtKEUK3Wqkp4HsQdYfZiHo',
INVALID_ACCESS_TOKEN: INVALID_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC05ZTNiLTQ2ZDQtYTU1Ni04OGI5ZGRjMmIwMzQiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMDY4Ny00YzQxLWI3MDctZWQxYmZjYTk3MmE3IiwiaWF0IjoxNzM4MzIzODc5LCJleHAiOjE3MzgzMjU2Nzl9.m73hHVpnw5uGNGrSuKxn6XtKEUK3Wqkp4HsQdYfZiHp', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC05ZTNiLTQ2ZDQtYTU1Ni04OGI5ZGRjMmIwMzQiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMDY4Ny00YzQxLWI3MDctZWQxYmZjYTk3MmE3IiwiaWF0IjoxNzM4MzIzODc5LCJleHAiOjE3MzgzMjU2Nzl9.m73hHVpnw5uGNGrSuKxn6XtKEUK3Wqkp4HsQdYfZiHp',
MEMBER_ACCESS_TOKEN: APPLE_JONY_MEMBER_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0zOTU3LTQ5MDgtOWMzNi0yOTI5YTIzZjgzNTciLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNzdkNS00Y2I2LWI2MGEtZjRhODM1YTg1ZDYxIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMzk1Ny00OTA4LTljMzYtMjkyOWEyM2Y4MzUzIiwiaWF0IjoxNzM5NDU5NTcwLCJleHAiOjMzMjk3MDU5NTcwfQ.Er7EEU4IP4YlGN79jCLR_6sUBqBfKx2M3G_qGiDpPRo', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0zOTU3LTQ5MDgtOWMzNi0yOTI5YTIzZjgzNTciLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNzdkNS00Y2I2LWI2MGEtZjRhODM1YTg1ZDYxIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMzk1Ny00OTA4LTljMzYtMjkyOWEyM2Y4MzUzIiwiaWF0IjoxNzM5NDU5NTcwLCJleHAiOjMzMjk3MDU5NTcwfQ.Er7EEU4IP4YlGN79jCLR_6sUBqBfKx2M3G_qGiDpPRo',
GUEST_ACCESS_TOKEN: APPLE_PHIL_GUEST_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC03MTY5LTQyY2YtYmM0Ny0xY2ZlZjE1MjY0YjgiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMTU1My00NWM2LWEwMjgtNWE5MDY0Y2NlMDdmIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtNzE2OS00MmNmLWJjNDctMWNmZWYxNTI2NGIxIiwiaWF0IjoxNzM5ODg4NDcwLCJleHAiOjMzMjk3NDg4NDcwfQ.0NEu-AWGv3l77rs-56Z5Gt0UTU7HDl6qUTHUcMWNrCc', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC03MTY5LTQyY2YtYmM0Ny0xY2ZlZjE1MjY0YjgiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMTU1My00NWM2LWEwMjgtNWE5MDY0Y2NlMDdmIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtNzE2OS00MmNmLWJjNDctMWNmZWYxNTI2NGIxIiwiaWF0IjoxNzM5ODg4NDcwLCJleHAiOjMzMjk3NDg4NDcwfQ.0NEu-AWGv3l77rs-56Z5Gt0UTU7HDl6qUTHUcMWNrCc',
ACME_JONY_MEMBER_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0zOTU3LTQ5MDgtOWMzNi0yOTI5YTIzZjgzNTciLCJ1c2VySWQiOiIyMDIwMjAyMC0zOTU3LTQ5MDgtOWMzNi0yOTI5YTIzZjgzNTciLCJ3b3Jrc3BhY2VJZCI6IjNiOGU2NDU4LTVmYzEtNGU2My04NTYzLTAwOGNjZGRhYTZkYiIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNzdkNS00Y2I2LWI2MGEtZjRhODM1YTg1ZDYxIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtZTEwYS00YzI3LWE5MGItYjA4YzU3YjAyZDQ1IiwidHlwZSI6IkFDQ0VTUyIsImF1dGhQcm92aWRlciI6InBhc3N3b3JkIiwiaWF0IjoxNzUyMDc4MDA0LCJleHAiOjMzMzA5Njc4MDA0fQ.JBtQCkNWsqAkzouxhcVjCEikV6A_-qr3IflE67NYQYY',
API_KEY_ACCESS_TOKEN: API_KEY_ACCESS_TOKEN:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzQ0OTgzNzUwLCJleHAiOjQ4OTg1ODM2OTMsImp0aSI6IjIwMjAyMDIwLWY0MDEtNGQ4YS1hNzMxLTY0ZDAwN2MyN2JhZCJ9.4xkkwz_uu2xzs_V8hJSaM15fGziT5zS3vq2lM48OHr0', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzQ0OTgzNzUwLCJleHAiOjQ4OTg1ODM2OTMsImp0aSI6IjIwMjAyMDIwLWY0MDEtNGQ4YS1hNzMxLTY0ZDAwN2MyN2JhZCJ9.4xkkwz_uu2xzs_V8hJSaM15fGziT5zS3vq2lM48OHr0',
}, },

View File

@ -9,12 +9,14 @@ import { handleDuplicateKeyError } from 'src/engine/api/graphql/workspace-query-
import { PostgresException } from 'src/engine/api/graphql/workspace-query-runner/utils/postgres-exception'; import { PostgresException } from 'src/engine/api/graphql/workspace-query-runner/utils/postgres-exception';
import { workspaceExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-exception-handler.util'; import { workspaceExceptionHandler } from 'src/engine/api/graphql/workspace-query-runner/utils/workspace-exception-handler.util';
import { WorkspaceQueryRunnerException } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception'; import { WorkspaceQueryRunnerException } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception';
import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { RecordTransformerException } from 'src/engine/core-modules/record-transformer/record-transformer.exception'; import { RecordTransformerException } from 'src/engine/core-modules/record-transformer/record-transformer.exception';
import { recordTransformerGraphqlApiExceptionHandler } from 'src/engine/core-modules/record-transformer/utils/record-transformer-graphql-api-exception-handler.util'; import { recordTransformerGraphqlApiExceptionHandler } from 'src/engine/core-modules/record-transformer/utils/record-transformer-graphql-api-exception-handler.util';
import { PermissionsException } from 'src/engine/metadata-modules/permissions/permissions.exception'; import { PermissionsException } from 'src/engine/metadata-modules/permissions/permissions.exception';
import { permissionGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/permissions/utils/permission-graphql-api-exception-handler.util'; import { permissionGraphqlApiExceptionHandler } from 'src/engine/metadata-modules/permissions/utils/permission-graphql-api-exception-handler.util';
import { TwentyORMException } from 'src/engine/twenty-orm/exceptions/twenty-orm.exception'; import { TwentyORMException } from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
import { twentyORMGraphqlApiExceptionHandler } from 'src/engine/twenty-orm/utils/twenty-orm-graphql-api-exception-handler.util'; import { twentyORMGraphqlApiExceptionHandler } from 'src/engine/twenty-orm/utils/twenty-orm-graphql-api-exception-handler.util';
import { authGraphqlApiExceptionHandler } from 'src/engine/core-modules/auth/utils/auth-graphql-api-exception-handler.util';
interface QueryFailedErrorWithCode extends QueryFailedError { interface QueryFailedErrorWithCode extends QueryFailedError {
code: string; code: string;
@ -48,6 +50,8 @@ export const workspaceQueryRunnerGraphqlApiExceptionHandler = (
return graphqlQueryRunnerExceptionHandler(error); return graphqlQueryRunnerExceptionHandler(error);
case error instanceof TwentyORMException: case error instanceof TwentyORMException:
return twentyORMGraphqlApiExceptionHandler(error); return twentyORMGraphqlApiExceptionHandler(error);
case error instanceof AuthException:
return authGraphqlApiExceptionHandler(error);
default: default:
throw error; throw error;
} }

View File

@ -1,63 +1,11 @@
import { Catch, ExceptionFilter } from '@nestjs/common'; import { Catch, ExceptionFilter } from '@nestjs/common';
import { t } from '@lingui/core/macro'; import { AuthException } from 'src/engine/core-modules/auth/auth.exception';
import { authGraphqlApiExceptionHandler } from 'src/engine/core-modules/auth/utils/auth-graphql-api-exception-handler.util';
import {
AuthException,
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import {
AuthenticationError,
ForbiddenError,
NotFoundError,
UserInputError,
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
@Catch(AuthException) @Catch(AuthException)
export class AuthGraphqlApiExceptionFilter implements ExceptionFilter { export class AuthGraphqlApiExceptionFilter implements ExceptionFilter {
catch(exception: AuthException) { catch(exception: AuthException) {
switch (exception.code) { return authGraphqlApiExceptionHandler(exception);
case AuthExceptionCode.CLIENT_NOT_FOUND:
throw new NotFoundError(exception);
case AuthExceptionCode.INVALID_INPUT:
throw new UserInputError(exception);
case AuthExceptionCode.FORBIDDEN_EXCEPTION:
case AuthExceptionCode.INSUFFICIENT_SCOPES:
case AuthExceptionCode.OAUTH_ACCESS_DENIED:
case AuthExceptionCode.SSO_AUTH_FAILED:
case AuthExceptionCode.USE_SSO_AUTH:
case AuthExceptionCode.SIGNUP_DISABLED:
case AuthExceptionCode.MISSING_ENVIRONMENT_VARIABLE:
case AuthExceptionCode.INVALID_JWT_TOKEN_TYPE:
throw new ForbiddenError(exception);
case AuthExceptionCode.GOOGLE_API_AUTH_DISABLED:
case AuthExceptionCode.MICROSOFT_API_AUTH_DISABLED:
throw new ForbiddenError(exception.message, {
userFriendlyMessage: t`Authentication is not enabled with this provider.`,
subCode: exception.code,
});
case AuthExceptionCode.EMAIL_NOT_VERIFIED:
case AuthExceptionCode.INVALID_DATA:
throw new ForbiddenError(exception.message, {
subCode: AuthExceptionCode.EMAIL_NOT_VERIFIED,
userFriendlyMessage: t`Email is not verified.`,
});
case AuthExceptionCode.UNAUTHENTICATED:
throw new AuthenticationError(exception.message, {
userFriendlyMessage: t`You must be authenticated to perform this action.`,
subCode: exception.code,
});
case AuthExceptionCode.USER_NOT_FOUND:
case AuthExceptionCode.WORKSPACE_NOT_FOUND:
throw new AuthenticationError(exception);
case AuthExceptionCode.INTERNAL_SERVER_ERROR:
case AuthExceptionCode.USER_WORKSPACE_NOT_FOUND:
throw exception;
default: {
const _exhaustiveCheck: never = exception.code;
throw exception;
}
}
} }
} }

View File

@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport'; import { PassportStrategy } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { t } from '@lingui/core/macro';
import { Strategy } from 'passport-jwt'; import { Strategy } from 'passport-jwt';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
@ -149,6 +150,9 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
new AuthException( new AuthException(
'UserWorkspace not found', 'UserWorkspace not found',
AuthExceptionCode.USER_WORKSPACE_NOT_FOUND, AuthExceptionCode.USER_WORKSPACE_NOT_FOUND,
{
userFriendlyMessage: t`User does not have access to this workspace`,
},
), ),
); );

View File

@ -0,0 +1,58 @@
import { t } from '@lingui/core/macro';
import {
AuthException,
AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception';
import {
AuthenticationError,
ForbiddenError,
NotFoundError,
UserInputError,
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
export const authGraphqlApiExceptionHandler = (exception: AuthException) => {
switch (exception.code) {
case AuthExceptionCode.CLIENT_NOT_FOUND:
throw new NotFoundError(exception);
case AuthExceptionCode.INVALID_INPUT:
throw new UserInputError(exception);
case AuthExceptionCode.FORBIDDEN_EXCEPTION:
case AuthExceptionCode.INSUFFICIENT_SCOPES:
case AuthExceptionCode.OAUTH_ACCESS_DENIED:
case AuthExceptionCode.SSO_AUTH_FAILED:
case AuthExceptionCode.USE_SSO_AUTH:
case AuthExceptionCode.SIGNUP_DISABLED:
case AuthExceptionCode.MISSING_ENVIRONMENT_VARIABLE:
case AuthExceptionCode.INVALID_JWT_TOKEN_TYPE:
throw new ForbiddenError(exception);
case AuthExceptionCode.GOOGLE_API_AUTH_DISABLED:
case AuthExceptionCode.MICROSOFT_API_AUTH_DISABLED:
throw new ForbiddenError(exception.message, {
userFriendlyMessage: t`Authentication is not enabled with this provider.`,
subCode: exception.code,
});
case AuthExceptionCode.EMAIL_NOT_VERIFIED:
case AuthExceptionCode.INVALID_DATA:
throw new ForbiddenError(exception.message, {
subCode: AuthExceptionCode.EMAIL_NOT_VERIFIED,
userFriendlyMessage: t`Email is not verified.`,
});
case AuthExceptionCode.UNAUTHENTICATED:
throw new AuthenticationError(exception.message, {
userFriendlyMessage: t`You must be authenticated to perform this action.`,
subCode: exception.code,
});
case AuthExceptionCode.USER_NOT_FOUND:
case AuthExceptionCode.WORKSPACE_NOT_FOUND:
case AuthExceptionCode.USER_WORKSPACE_NOT_FOUND:
throw new AuthenticationError(exception);
case AuthExceptionCode.INTERNAL_SERVER_ERROR:
throw exception;
default: {
const _exhaustiveCheck: never = exception.code;
throw exception;
}
}
};

View File

@ -3,35 +3,27 @@ import { CreateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.createMany`) @WorkspaceQueryHook(`workspaceMember.createMany`)
export class WorkspaceMemberCreateManyPreQueryHook export class WorkspaceMemberCreateManyPreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<CreateManyResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: CreateManyResolverArgs,
): Promise<CreateManyResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -3,35 +3,27 @@ import { CreateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.createOne`) @WorkspaceQueryHook(`workspaceMember.createOne`)
export class WorkspaceMemberCreateOnePreQueryHook export class WorkspaceMemberCreateOnePreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<CreateOneResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: CreateOneResolverArgs,
): Promise<CreateOneResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -3,35 +3,27 @@ import { DeleteManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.deleteMany`) @WorkspaceQueryHook(`workspaceMember.deleteMany`)
export class WorkspaceMemberDeleteManyPreQueryHook export class WorkspaceMemberDeleteManyPreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<DeleteManyResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: DeleteManyResolverArgs,
): Promise<DeleteManyResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -1,12 +1,23 @@
import { InjectRepository } from '@nestjs/typeorm';
import { isDefined } from 'twenty-shared/utils';
import { Repository } from 'typeorm';
import { WorkspacePreQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface'; import { WorkspacePreQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service'; import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@WorkspaceQueryHook(`workspaceMember.deleteOne`) @WorkspaceQueryHook(`workspaceMember.deleteOne`)
export class WorkspaceMemberDeleteOnePreQueryHook export class WorkspaceMemberDeleteOnePreQueryHook
@ -14,6 +25,8 @@ export class WorkspaceMemberDeleteOnePreQueryHook
{ {
constructor( constructor(
private readonly twentyORMManager: TwentyORMManager, private readonly twentyORMManager: TwentyORMManager,
@InjectRepository(UserWorkspace, 'core')
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService, private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {} ) {}
@ -49,6 +62,41 @@ export class WorkspaceMemberDeleteOnePreQueryHook
authorId, authorId,
}); });
const workspaceMemberRepository =
await this.twentyORMManager.getRepository<WorkspaceMemberWorkspaceEntity>(
'workspaceMember',
);
const workspaceMember = await workspaceMemberRepository.findOne({
where: {
id: targettedWorkspaceMemberId,
},
});
if (!isDefined(workspaceMember)) {
// TODO: once this is migrated to userWorkspace service we should throw UserWorkspaceException
throw new PermissionsException(
'Workspace member not found',
PermissionsExceptionCode.WORKSPACE_MEMBER_NOT_FOUND,
);
}
const userWorkspace = await this.userWorkspaceRepository.findOne({
where: {
workspaceId: workspace.id,
userId: workspaceMember.userId,
},
});
if (!isDefined(userWorkspace)) {
throw new PermissionsException(
'User workspace not found',
PermissionsExceptionCode.USER_WORKSPACE_NOT_FOUND,
);
}
await this.userWorkspaceRepository.delete(userWorkspace.id);
return payload; return payload;
} }
} }

View File

@ -3,35 +3,27 @@ import { DeleteManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.destroyMany`) @WorkspaceQueryHook(`workspaceMember.destroyMany`)
export class WorkspaceMemberDestroyManyPreQueryHook export class WorkspaceMemberDestroyManyPreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<DeleteManyResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: DeleteManyResolverArgs,
): Promise<DeleteManyResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -3,36 +3,27 @@ import { DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.destroyOne`) @WorkspaceQueryHook(`workspaceMember.destroyOne`)
export class WorkspaceMemberDestroyOnePreQueryHook export class WorkspaceMemberDestroyOnePreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<DeleteOneResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: DeleteOneResolverArgs,
): Promise<DeleteOneResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
targettedWorkspaceMemberId: payload.id,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -3,35 +3,27 @@ import { RestoreManyResolverArgs } from 'src/engine/api/graphql/workspace-resolv
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.restoreMany`) @WorkspaceQueryHook(`workspaceMember.restoreMany`)
export class WorkspaceMemberRestoreManyPreQueryHook export class WorkspaceMemberRestoreManyPreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<RestoreManyResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: RestoreManyResolverArgs,
): Promise<RestoreManyResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -3,36 +3,27 @@ import { RestoreOneResolverArgs } from 'src/engine/api/graphql/workspace-resolve
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.restoreOne`) @WorkspaceQueryHook(`workspaceMember.restoreOne`)
export class WorkspaceMemberRestoreOnePreQueryHook export class WorkspaceMemberRestoreOnePreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<RestoreOneResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: RestoreOneResolverArgs,
): Promise<RestoreOneResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
targettedWorkspaceMemberId: payload.id,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -3,35 +3,27 @@ import { UpdateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolve
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceMemberPreQueryHookService } from 'src/modules/workspace-member/query-hooks/workspace-member-pre-query-hook.service';
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
import {
PermissionsException,
PermissionsExceptionCode,
PermissionsExceptionMessage,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
@WorkspaceQueryHook(`workspaceMember.updateMany`) @WorkspaceQueryHook(`workspaceMember.updateMany`)
export class WorkspaceMemberUpdateManyPreQueryHook export class WorkspaceMemberUpdateManyPreQueryHook
implements WorkspacePreQueryHookInstance implements WorkspacePreQueryHookInstance
{ {
constructor( constructor() {}
private readonly workspaceMemberPreQueryHookService: WorkspaceMemberPreQueryHookService,
) {}
async execute( async execute(authContext: AuthContext): Promise<UpdateManyResolverArgs> {
authContext: AuthContext,
objectName: string,
payload: UpdateManyResolverArgs,
): Promise<UpdateManyResolverArgs> {
const workspace = authContext.workspace; const workspace = authContext.workspace;
workspaceValidator.assertIsDefinedOrThrow(workspace); workspaceValidator.assertIsDefinedOrThrow(workspace);
await this.workspaceMemberPreQueryHookService.validateWorkspaceMemberUpdatePermissionOrThrow( throw new PermissionsException(
{ PermissionsExceptionMessage.PERMISSION_DENIED,
userWorkspaceId: authContext.userWorkspaceId, PermissionsExceptionCode.PERMISSION_DENIED,
workspaceId: workspace.id,
apiKey: authContext.apiKey,
workspaceMemberId: authContext.workspaceMemberId,
},
); );
return payload;
} }
} }

View File

@ -19,7 +19,7 @@ describe('BillingController (integration)', () => {
await client await client
.post('/webhooks/stripe') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.send(JSON.stringify(productUpdatedPayload)) .send(JSON.stringify(productUpdatedPayload))
@ -30,7 +30,7 @@ describe('BillingController (integration)', () => {
await client await client
.post('/webhooks/stripe') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.send(JSON.stringify(priceCreatedPayload)) .send(JSON.stringify(priceCreatedPayload))
@ -52,7 +52,7 @@ describe('BillingController (integration)', () => {
await client await client
.post('/webhooks/stripe') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.send(JSON.stringify(subscriptionCreatedPayload)) .send(JSON.stringify(subscriptionCreatedPayload))
@ -64,7 +64,7 @@ describe('BillingController (integration)', () => {
await client await client
.post('/webhooks/stripe') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.send(JSON.stringify(entitlementUpdatedPayload)) .send(JSON.stringify(entitlementUpdatedPayload))
@ -84,7 +84,7 @@ describe('BillingController (integration)', () => {
await client await client
.post('/webhooks/stripe') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.send(JSON.stringify(entitlementUpdatedPayload)) .send(JSON.stringify(entitlementUpdatedPayload))
@ -103,7 +103,7 @@ describe('BillingController (integration)', () => {
await client await client
.post('/webhooks/stripe') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'invalid-signature') .set('stripe-signature', 'invalid-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.send(JSON.stringify(entitlementUpdatedPayload)) .send(JSON.stringify(entitlementUpdatedPayload))

View File

@ -91,7 +91,7 @@ describe('${queryName}Resolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', \`Bearer \${ADMIN_ACCESS_TOKEN}\`) .set('Authorization', \`Bearer \${APPLE_JANE_ADMIN_ACCESS_TOKEN}\`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -34,7 +34,7 @@ describe('attachmentsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -25,7 +25,7 @@ describe('blocklistsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -27,7 +27,7 @@ describe('calendarChannelEventAssociationsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -35,7 +35,7 @@ describe('calendarChannelsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -30,7 +30,7 @@ describe('calendarEventParticipantsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -32,7 +32,7 @@ describe('companiesResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -32,7 +32,7 @@ describe('connectedAccountsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -36,7 +36,7 @@ describe('favoritesResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -27,7 +27,7 @@ describe('indexMetadatasResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -28,7 +28,7 @@ describe('messageChannelMessageAssociationsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -38,7 +38,7 @@ describe('messageChannelsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -29,7 +29,7 @@ describe('messageParticipantsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -23,7 +23,7 @@ describe('messageThreadsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -29,7 +29,7 @@ describe('noteTargetsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -26,7 +26,7 @@ describe('notesResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -35,7 +35,7 @@ describe('objectsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -30,7 +30,7 @@ describe('opportunitiesResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -32,7 +32,7 @@ describe('peopleResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -26,7 +26,7 @@ describe('petsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -23,7 +23,7 @@ describe('serverlessFunctionsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -29,7 +29,7 @@ describe('taskTargetsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -29,7 +29,7 @@ describe('tasksResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -40,7 +40,7 @@ describe('timelineActivitiesResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -28,7 +28,7 @@ describe('viewFieldsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -28,7 +28,7 @@ describe('viewFiltersResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -26,7 +26,7 @@ describe('viewSortsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -31,7 +31,7 @@ describe('viewsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -26,7 +26,7 @@ describe('workflowAutomatedTriggersResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -29,7 +29,7 @@ describe('workflowVersionsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -27,7 +27,7 @@ describe('workflowsResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -31,7 +31,7 @@ describe('workspaceMembersResolver (e2e)', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -31,7 +31,7 @@ describe('granularObjectRecordsPermissions', () => {
const rolesResponse = await client const rolesResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRolesQuery); .send(getRolesQuery);
originalMemberRoleId = rolesResponse.body.data.getRoles.find( originalMemberRoleId = rolesResponse.body.data.getRoles.find(
@ -55,7 +55,7 @@ describe('granularObjectRecordsPermissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(restoreMemberRoleQuery); .send(restoreMemberRoleQuery);
}); });

View File

@ -37,7 +37,7 @@ describe('permissionsOnRelations', () => {
const rolesResponse = await client const rolesResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRolesQuery); .send(getRolesQuery);
originalMemberRoleId = rolesResponse.body.data.getRoles.find( originalMemberRoleId = rolesResponse.body.data.getRoles.find(
@ -91,7 +91,7 @@ describe('permissionsOnRelations', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(restoreMemberRoleQuery); .send(restoreMemberRoleQuery);
}); });

View File

@ -20,7 +20,7 @@ describe('api key and webhooks permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -32,7 +32,7 @@ describe('Granular settings permissions', () => {
const rolesResponse = await client const rolesResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRolesQuery); .send(getRolesQuery);
originalMemberRoleId = rolesResponse.body.data.getRoles.find( originalMemberRoleId = rolesResponse.body.data.getRoles.find(
@ -62,7 +62,7 @@ describe('Granular settings permissions', () => {
const createRoleResponse = await client const createRoleResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(createRoleQuery); .send(createRoleQuery);
customRoleId = createRoleResponse.body.data.createOneRole.id; customRoleId = createRoleResponse.body.data.createOneRole.id;
@ -85,10 +85,10 @@ describe('Granular settings permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(upsertSettingPermissionsQuery); .send(upsertSettingPermissionsQuery);
// Assign the custom role to JONY (who uses MEMBER_ACCESS_TOKEN) // Assign the custom role to JONY (who uses APPLE_JONY_MEMBER_ACCESS_TOKEN)
await updateWorkspaceMemberRole({ await updateWorkspaceMemberRole({
client, client,
roleId: customRoleId, roleId: customRoleId,
@ -113,7 +113,7 @@ describe('Granular settings permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(restoreMemberRoleQuery); .send(restoreMemberRoleQuery);
// Delete the custom role // Delete the custom role
@ -121,7 +121,7 @@ describe('Granular settings permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(deleteRoleQuery); .send(deleteRoleQuery);
}); });
@ -147,7 +147,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/metadata') .post('/metadata')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send({ query: print(createObjectQuery), variables }); .send({ query: print(createObjectQuery), variables });
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -166,7 +166,7 @@ describe('Granular settings permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send({ .send({
query: print(deleteObjectQuery), query: print(deleteObjectQuery),
variables: deleteObjectVariables, variables: deleteObjectVariables,
@ -192,7 +192,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(updateWorkspaceQuery); .send(updateWorkspaceQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -218,7 +218,7 @@ describe('Granular settings permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(restoreWorkspaceQuery); .send(restoreWorkspaceQuery);
}); });
}); });
@ -241,7 +241,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(createWorkflowQuery); .send(createWorkflowQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -260,7 +260,7 @@ describe('Granular settings permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(graphqlOperation); .send(graphqlOperation);
}); });
}); });
@ -282,7 +282,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(createRoleQuery); .send(createRoleQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -308,7 +308,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(inviteWorkspaceMemberQuery); .send(inviteWorkspaceMemberQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -334,7 +334,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(createApiKeyQuery); .send(createApiKeyQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -367,7 +367,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRoleQuery); .send(getRoleQuery);
const customRole = response.body.data.getRoles.find( const customRole = response.body.data.getRoles.find(
@ -406,7 +406,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(upsertSecurityPermissionQuery); .send(upsertSecurityPermissionQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -431,7 +431,7 @@ describe('Granular settings permissions', () => {
const roleResponse = await client const roleResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRoleQuery); .send(getRoleQuery);
const updatedRole = roleResponse.body.data.getRoles.find( const updatedRole = roleResponse.body.data.getRoles.find(
@ -463,7 +463,7 @@ describe('Granular settings permissions', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(upsertReducedPermissionsQuery); .send(upsertReducedPermissionsQuery);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -486,7 +486,7 @@ describe('Granular settings permissions', () => {
const roleResponse = await client const roleResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRoleQuery); .send(getRoleQuery);
const updatedRole = roleResponse.body.data.getRoles.find( const updatedRole = roleResponse.body.data.getRoles.find(

View File

@ -18,7 +18,7 @@ async function assertPermissionDeniedForMemberWithMemberRole({
}) { }) {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -49,7 +49,7 @@ describe('roles permissions', () => {
const resp = await client const resp = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query); .send(query);
adminRoleId = resp.body.data.getRoles.find( adminRoleId = resp.body.data.getRoles.find(
@ -84,7 +84,7 @@ describe('roles permissions', () => {
const resp = await client const resp = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query); .send(query);
expect(resp.status).toBe(200); expect(resp.status).toBe(200);
@ -193,7 +193,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -221,7 +221,7 @@ describe('roles permissions', () => {
const resp = await client const resp = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(getRolesQuery); .send(getRolesQuery);
const memberRoleId = resp.body.data.getRoles.find( const memberRoleId = resp.body.data.getRoles.find(
@ -247,7 +247,7 @@ describe('roles permissions', () => {
// Act and assert // Act and assert
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(updateRoleQuery) .send(updateRoleQuery)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -271,7 +271,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(rollbackRoleUpdateQuery) .send(rollbackRoleUpdateQuery)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -313,7 +313,7 @@ describe('roles permissions', () => {
const result = await client const result = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -328,7 +328,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(deleteOneRoleQuery); .send(deleteOneRoleQuery);
}); });
}); });
@ -349,7 +349,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.then((res) => { .then((res) => {
createdEditableRoleId = res.body.data.createOneRole.id; createdEditableRoleId = res.body.data.createOneRole.id;
@ -363,7 +363,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(deleteOneRoleQuery); .send(deleteOneRoleQuery);
}); });
@ -395,7 +395,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -424,7 +424,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -497,7 +497,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -522,7 +522,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -595,7 +595,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -619,7 +619,7 @@ describe('roles permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -69,7 +69,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -98,7 +98,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -129,7 +129,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -158,7 +158,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -189,7 +189,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -218,7 +218,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -248,7 +248,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -277,7 +277,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -310,7 +310,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -340,7 +340,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -369,7 +369,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -400,7 +400,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -429,7 +429,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -460,7 +460,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -489,7 +489,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -520,7 +520,7 @@ describe('Security permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -549,7 +549,7 @@ describe('Security permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -19,7 +19,7 @@ describe('workspace invitation permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -45,7 +45,7 @@ describe('workspace invitation permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -72,7 +72,7 @@ describe('workspace invitation permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -96,7 +96,7 @@ describe('workspace invitation permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -1,8 +1,6 @@
import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util';
import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete-one-operation-factory.util'; import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete-one-operation-factory.util';
import { makeGraphqlAPIRequestWithAcmeMemberRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-acme-member-role.util';
import { makeGraphqlAPIRequestWithMemberRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-member-role.util'; import { makeGraphqlAPIRequestWithMemberRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-member-role.util';
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
import { restoreOneOperationFactory } from 'test/integration/graphql/utils/restore-one-operation-factory.util';
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util'; import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
@ -68,37 +66,6 @@ describe('workspace members permissions', () => {
}); });
describe('deleteOne', () => { describe('deleteOne', () => {
afterEach(async () => {
// Restore the deleted user to maintain test isolation
const restoreOperation = restoreOneOperationFactory({
objectMetadataSingularName: 'workspaceMember',
gqlFields: WORKSPACE_MEMBER_GQL_FIELDS,
recordId: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY,
});
await makeGraphqlAPIRequest(restoreOperation);
});
it('should allow delete when user is deleting themself (member role)', async () => {
const deleteOperation = deleteOneOperationFactory({
objectMetadataSingularName: 'workspaceMember',
gqlFields: WORKSPACE_MEMBER_GQL_FIELDS,
recordId: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY,
});
const deleteResponse =
await makeGraphqlAPIRequestWithMemberRole(deleteOperation);
expect(deleteResponse.body.data).toStrictEqual({
deleteWorkspaceMember: {
id: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY,
name: {
firstName: 'Jony',
},
},
});
expect(deleteResponse.body.errors).toBeUndefined();
});
it('should throw when user does not have permission (member role)', async () => { it('should throw when user does not have permission (member role)', async () => {
const graphqlOperation = deleteOneOperationFactory({ const graphqlOperation = deleteOneOperationFactory({
objectMetadataSingularName: 'workspaceMember', objectMetadataSingularName: 'workspaceMember',
@ -116,75 +83,26 @@ describe('workspace members permissions', () => {
); );
expect(response.body.errors[0].extensions.code).toBe(ErrorCode.FORBIDDEN); expect(response.body.errors[0].extensions.code).toBe(ErrorCode.FORBIDDEN);
}); });
});
describe('restoreOne', () => { it('should allow delete when user is deleting themself (member role)', async () => {
it('should allow restore when user is restoring themself (member role)', async () => { const deleteOperation = deleteOneOperationFactory({
const restoreOperation = restoreOneOperationFactory({
objectMetadataSingularName: 'workspaceMember', objectMetadataSingularName: 'workspaceMember',
gqlFields: WORKSPACE_MEMBER_GQL_FIELDS, gqlFields: WORKSPACE_MEMBER_GQL_FIELDS,
recordId: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY, recordId: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY,
}); });
const response = const deleteResponse =
await makeGraphqlAPIRequestWithMemberRole(restoreOperation); await makeGraphqlAPIRequestWithAcmeMemberRole(deleteOperation);
expect(response.body.data).toStrictEqual({ expect(deleteResponse.body.data).toStrictEqual({
restoreWorkspaceMember: { deleteWorkspaceMember: {
id: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY, id: WORKSPACE_MEMBER_DATA_SEED_IDS.JONY,
name: { name: {
firstName: 'Jony', firstName: 'Jony',
}, },
}, },
}); });
expect(response.body.errors).toBeUndefined(); expect(deleteResponse.body.errors).toBeUndefined();
});
it('should throw when user does not have permission (member role)', async () => {
const restoreOperation = restoreOneOperationFactory({
objectMetadataSingularName: 'workspaceMember',
gqlFields: WORKSPACE_MEMBER_GQL_FIELDS,
recordId: WORKSPACE_MEMBER_DATA_SEED_IDS.TIM,
});
const response =
await makeGraphqlAPIRequestWithMemberRole(restoreOperation);
expect(response.body.data).toStrictEqual({
restoreWorkspaceMember: null,
});
expect(response.body.errors).toBeDefined();
expect(response.body.errors[0].message).toBe(
PermissionsExceptionMessage.PERMISSION_DENIED,
);
expect(response.body.errors[0].extensions.code).toBe(ErrorCode.FORBIDDEN);
});
});
describe('createOne', () => {
it('should throw when user does not have permission (member role)', async () => {
const createOperation = createOneOperationFactory({
objectMetadataSingularName: 'workspaceMember',
gqlFields: WORKSPACE_MEMBER_GQL_FIELDS,
data: {
userId: 'cc80c2e9-3002-46ac-bcc6-24e524713f21',
name: {
firstName: 'New',
},
},
});
const response =
await makeGraphqlAPIRequestWithMemberRole(createOperation);
expect(response.body.data).toStrictEqual({
createWorkspaceMember: null,
});
expect(response.body.errors).toBeDefined();
expect(response.body.errors[0].message).toBe(
PermissionsExceptionMessage.PERMISSION_DENIED,
);
expect(response.body.errors[0].extensions.code).toBe(ErrorCode.FORBIDDEN);
}); });
}); });
}); });

View File

@ -69,7 +69,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -99,7 +99,7 @@ describe('workspace permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -128,7 +128,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -159,7 +159,7 @@ describe('workspace permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -188,7 +188,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -219,7 +219,7 @@ describe('workspace permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -248,7 +248,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -279,7 +279,7 @@ describe('workspace permissions', () => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -308,7 +308,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -340,7 +340,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -373,7 +373,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -419,7 +419,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {
@ -460,7 +460,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect((res) => { .expect((res) => {
expect(res.body.data).toBeDefined(); expect(res.body.data).toBeDefined();
@ -493,7 +493,7 @@ describe('workspace permissions', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send(queryData) .send(queryData)
.expect(200) .expect(200)
.expect((res) => { .expect((res) => {

View File

@ -18,7 +18,7 @@ describe('deleteUser', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(query) .send(query)
.expect((res) => { .expect((res) => {
expect(res.body.data).toBeNull(); expect(res.body.data).toBeNull();

View File

@ -23,7 +23,7 @@ describe('workflowResolver', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData); .send(queryData);
}); });
@ -40,7 +40,7 @@ describe('workflowResolver', () => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData); .send(queryData);
}); });
@ -67,7 +67,7 @@ describe('workflowResolver', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData); .send(queryData);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -94,7 +94,7 @@ describe('workflowResolver', () => {
const deleteResponse = await client const deleteResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(deleteQueryData); .send(deleteQueryData);
expect(deleteResponse.status).toBe(200); expect(deleteResponse.status).toBe(200);
@ -115,7 +115,7 @@ describe('workflowResolver', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData); .send(queryData);
expect(response.status).toBe(200); expect(response.status).toBe(200);
@ -146,7 +146,7 @@ describe('workflowResolver', () => {
const workflowVersionsResponse = await client const workflowVersionsResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryWorkflowVersionsData); .send(queryWorkflowVersionsData);
expect(workflowVersionsResponse.status).toBe(200); expect(workflowVersionsResponse.status).toBe(200);
@ -172,7 +172,7 @@ describe('workflowResolver', () => {
const restoreResponse = await client const restoreResponse = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(restoreQueryData); .send(restoreQueryData);
expect(restoreResponse.status).toBe(200); expect(restoreResponse.status).toBe(200);
@ -199,7 +199,7 @@ describe('workflowResolver', () => {
const response = await client const response = await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(queryData); .send(queryData);
expect(response.status).toBe(200); expect(response.status).toBe(200);

View File

@ -5,6 +5,6 @@ export const deleteRole = async (client: any, roleId: string) => {
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(deleteRoleQuery); .send(deleteRoleQuery);
}; };

View File

@ -0,0 +1,21 @@
import { ASTNode, print } from 'graphql';
import request from 'supertest';
type GraphqlOperation = {
query: ASTNode;
variables?: Record<string, unknown>;
};
export const makeGraphqlAPIRequestWithAcmeMemberRole = (
graphqlOperation: GraphqlOperation,
) => {
const client = request(`http://localhost:${APP_PORT}`);
return client
.post('/graphql')
.set('Authorization', `Bearer ${ACME_JONY_MEMBER_ACCESS_TOKEN}`)
.send({
query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {},
});
};

View File

@ -13,7 +13,7 @@ export const makeGraphqlAPIRequestWithGuestRole = (
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${GUEST_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_PHIL_GUEST_ACCESS_TOKEN}`)
.send({ .send({
query: print(graphqlOperation.query), query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {}, variables: graphqlOperation.variables || {},

View File

@ -13,7 +13,7 @@ export const makeGraphqlAPIRequestWithMemberRole = (
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send({ .send({
query: print(graphqlOperation.query), query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {}, variables: graphqlOperation.variables || {},

View File

@ -11,7 +11,7 @@ export const makeGraphqlAPIRequest = (graphqlOperation: GraphqlOperation) => {
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send({ .send({
query: print(graphqlOperation.query), query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {}, variables: graphqlOperation.variables || {},

View File

@ -26,6 +26,6 @@ export const updateWorkspaceMemberRole = async ({
await client await client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send(updateMemberRoleQuery); .send(updateMemberRoleQuery);
}; };

View File

@ -5,6 +5,7 @@ exports[`Object metadata update should fail when labelIdentifier is not a TEXT o
{ {
"extensions": { "extensions": {
"code": "BAD_USER_INPUT", "code": "BAD_USER_INPUT",
"subCode": "INVALID_OBJECT_INPUT",
"userFriendlyMessage": "An error occurred.", "userFriendlyMessage": "An error occurred.",
}, },
"message": "labelIdentifierFieldMetadataId validation failed: it must be a TEXT or FULL_NAME field metadata type id", "message": "labelIdentifierFieldMetadataId validation failed: it must be a TEXT or FULL_NAME field metadata type id",
@ -18,6 +19,7 @@ exports[`Object metadata update should fail when labelIdentifier is not a known
{ {
"extensions": { "extensions": {
"code": "BAD_USER_INPUT", "code": "BAD_USER_INPUT",
"subCode": "INVALID_OBJECT_INPUT",
"userFriendlyMessage": "An error occurred.", "userFriendlyMessage": "An error occurred.",
}, },
"message": "labelIdentifierFieldMetadataId validation failed: related field metadata not found", "message": "labelIdentifierFieldMetadataId validation failed: related field metadata not found",

View File

@ -13,7 +13,7 @@ export const makeMetadataAPIRequestWithMemberRole = (
return client return client
.post('/metadata') .post('/metadata')
.set('Authorization', `Bearer ${MEMBER_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JONY_MEMBER_ACCESS_TOKEN}`)
.send({ .send({
query: print(graphqlOperation.query), query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {}, variables: graphqlOperation.variables || {},

View File

@ -11,7 +11,7 @@ export const makeMetadataAPIRequest = (graphqlOperation: GraphqlOperation) => {
return client return client
.post('/metadata') .post('/metadata')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send({ .send({
query: print(graphqlOperation.query), query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {}, variables: graphqlOperation.variables || {},

View File

@ -102,7 +102,7 @@ describe('Core REST API Create Many endpoint', () => {
method: 'post', method: 'post',
path: `/batch/people`, path: `/batch/people`,
body: requestBody, body: requestBody,
bearer: ADMIN_ACCESS_TOKEN, bearer: APPLE_JANE_ADMIN_ACCESS_TOKEN,
}) })
.expect(201) .expect(201)
.expect((res) => { .expect((res) => {

View File

@ -87,7 +87,7 @@ describe('Core REST API Create One endpoint', () => {
method: 'post', method: 'post',
path: `/people`, path: `/people`,
body: requestBody, body: requestBody,
bearer: ADMIN_ACCESS_TOKEN, bearer: APPLE_JANE_ADMIN_ACCESS_TOKEN,
}) })
.expect(201) .expect(201)
.expect((res) => { .expect((res) => {

View File

@ -1,7 +1,7 @@
import { ASTNode, print } from 'graphql'; import { ASTNode, print } from 'graphql';
import request from 'supertest'; import request from 'supertest';
/* global APP_PORT, ADMIN_ACCESS_TOKEN */ /* global APP_PORT, APPLE_JANE_ADMIN_ACCESS_TOKEN */
type GraphqlOperation = { type GraphqlOperation = {
query: ASTNode; query: ASTNode;
@ -15,7 +15,7 @@ export const makeAdminPanelAPIRequest = (
return client return client
.post('/graphql') .post('/graphql')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${APPLE_JANE_ADMIN_ACCESS_TOKEN}`)
.send({ .send({
query: print(graphqlOperation.query), query: print(graphqlOperation.query),
variables: graphqlOperation.variables || {}, variables: graphqlOperation.variables || {},