mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-25 04:55:30 +03:00
Throw an error if workspace id has no object (#2857)
* Throw an error if workspace id has no object * Request only plurial object names * Fix tests * Fix query * Handle graphql errors
This commit is contained in:
parent
06936c3c2a
commit
3cd1ec21e6
@ -27,6 +27,7 @@ import OptionTable from '@site/src/theme/OptionTable'
|
||||
['REDIS_HOST', '127.0.0.1', 'Redis connection host'],
|
||||
['REDIS_PORT', '6379', 'Redis connection port'],
|
||||
['FRONT_BASE_URL', 'http://localhost:3001', 'Url to the hosted frontend'],
|
||||
['SERVER_URL', 'http://localhost:3000', 'Url to the hosted server'],
|
||||
['PORT', '3000', 'Port'],
|
||||
]}></OptionTable>
|
||||
|
||||
|
@ -30,3 +30,4 @@ SIGN_IN_PREFILLED=true
|
||||
# REDIS_HOST=127.0.0.1
|
||||
# REDIS_PORT=6379
|
||||
# DEMO_WORKSPACE_IDS=REPLACE_ME_WITH_A_RANDOM_UUID
|
||||
# SERVER_URL=http://localhost:3000
|
||||
|
@ -12,6 +12,7 @@ import { UpdateVariablesFactory } from 'src/core/api-rest/api-rest-query-builder
|
||||
import { GetVariablesFactory } from 'src/core/api-rest/api-rest-query-builder/factories/get-variables.factory';
|
||||
import { ObjectMetadataService } from 'src/metadata/object-metadata/object-metadata.service';
|
||||
import { TokenService } from 'src/core/auth/services/token.service';
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
|
||||
describe('ApiRestQueryBuilderFactory', () => {
|
||||
let service: ApiRestQueryBuilderFactory;
|
||||
@ -31,6 +32,7 @@ describe('ApiRestQueryBuilderFactory', () => {
|
||||
{ provide: GetVariablesFactory, useValue: {} },
|
||||
{ provide: ObjectMetadataService, useValue: {} },
|
||||
{ provide: TokenService, useValue: {} },
|
||||
{ provide: EnvironmentService, useValue: {} },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
@ -17,6 +17,7 @@ import { parsePath } from 'src/core/api-rest/api-rest-query-builder/utils/parse-
|
||||
import { computeDepth } from 'src/core/api-rest/api-rest-query-builder/utils/compute-depth.utils';
|
||||
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||
import { ApiRestQuery } from 'src/core/api-rest/types/api-rest-query.type';
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
|
||||
@Injectable()
|
||||
export class ApiRestQueryBuilderFactory {
|
||||
@ -32,6 +33,7 @@ export class ApiRestQueryBuilderFactory {
|
||||
private readonly getVariablesFactory: GetVariablesFactory,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly tokenService: TokenService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
) {}
|
||||
|
||||
async getObjectMetadata(request: Request): Promise<{
|
||||
@ -43,29 +45,27 @@ export class ApiRestQueryBuilderFactory {
|
||||
const objectMetadataItems =
|
||||
await this.objectMetadataService.findManyWithinWorkspace(workspaceId);
|
||||
|
||||
const { id, object: parsedObject } = parsePath(request);
|
||||
|
||||
let objectNameKey = 'namePlural';
|
||||
let wrongObjectNameKey = 'nameSingular';
|
||||
|
||||
if (id) {
|
||||
objectNameKey = 'nameSingular';
|
||||
wrongObjectNameKey = 'namePlural';
|
||||
if (!objectMetadataItems.length) {
|
||||
throw new BadRequestException(
|
||||
`No object was found for the workspace associated with this API key. You may generate a new one here ${this.environmentService.getFrontBaseUrl()}/settings/developers/api-keys`,
|
||||
);
|
||||
}
|
||||
|
||||
const { object: parsedObject } = parsePath(request);
|
||||
|
||||
const [objectMetadata] = objectMetadataItems.filter(
|
||||
(object) => object[objectNameKey] === parsedObject,
|
||||
(object) => object.namePlural === parsedObject,
|
||||
);
|
||||
|
||||
if (!objectMetadata) {
|
||||
const [wrongObjectMetadata] = objectMetadataItems.filter(
|
||||
(object) => object[wrongObjectNameKey] === parsedObject,
|
||||
(object) => object.nameSingular === parsedObject,
|
||||
);
|
||||
|
||||
let hint = 'eg: companies';
|
||||
|
||||
if (wrongObjectMetadata) {
|
||||
hint = `Did you mean '${wrongObjectMetadata[objectNameKey]}'?`;
|
||||
hint = `Did you mean '${wrongObjectMetadata.namePlural}'?`;
|
||||
}
|
||||
|
||||
throw new BadRequestException(
|
||||
|
@ -7,7 +7,7 @@ import { ApiRestResponse } from 'src/core/api-rest/types/api-rest-response.type'
|
||||
|
||||
const handleResult = (res: Response, result: ApiRestResponse) => {
|
||||
if (result.data.error) {
|
||||
res.status(400).send(result.data);
|
||||
res.status(result.data.status || 400).send({ error: result.data.error });
|
||||
} else {
|
||||
res.send(result.data);
|
||||
}
|
||||
|
@ -21,15 +21,15 @@ export class ApiRestService {
|
||||
request: Request,
|
||||
data: ApiRestQuery,
|
||||
): Promise<ApiRestResponse> {
|
||||
return await axios.post(
|
||||
`${request.protocol}://${request.get('host')}/graphql`,
|
||||
data,
|
||||
{
|
||||
const baseUrl =
|
||||
this.environmentService.getServerUrl() ||
|
||||
`${request.protocol}://${request.get('host')}`;
|
||||
|
||||
return await axios.post(`${baseUrl}/graphql`, data, {
|
||||
headers: {
|
||||
Authorization: request.headers.authorization,
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async get(request: Request): Promise<ApiRestResponse> {
|
||||
@ -38,7 +38,7 @@ export class ApiRestService {
|
||||
|
||||
return await this.callGraphql(request, data);
|
||||
} catch (err) {
|
||||
return { data: { error: `${err}` } };
|
||||
return { data: { error: `${err}`, status: err.response.status } };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
export type ApiRestResponse = { data: { error?: string } };
|
||||
export type ApiRestResponse = { data: { error?: string; status?: number } };
|
||||
|
@ -50,6 +50,10 @@ export class EnvironmentService {
|
||||
return this.configService.get<string>('FRONT_BASE_URL')!;
|
||||
}
|
||||
|
||||
getServerUrl(): string {
|
||||
return this.configService.get<string>('SERVER_URL')!;
|
||||
}
|
||||
|
||||
getAccessTokenSecret(): string {
|
||||
return this.configService.get<string>('ACCESS_TOKEN_SECRET')!;
|
||||
}
|
||||
|
@ -60,6 +60,11 @@ export class EnvironmentVariables {
|
||||
@IsUrl({ require_tld: false })
|
||||
FRONT_BASE_URL: string;
|
||||
|
||||
// Frontend URL
|
||||
@IsUrl({ require_tld: false })
|
||||
@IsOptional()
|
||||
SERVER_URL: string;
|
||||
|
||||
// Json Web Token
|
||||
@IsString()
|
||||
ACCESS_TOKEN_SECRET: string;
|
||||
|
Loading…
Reference in New Issue
Block a user