Skip to content

Commit

Permalink
✨ Added connection token for protected routes
Browse files Browse the repository at this point in the history
  • Loading branch information
naelob committed Jan 8, 2024
1 parent f95962d commit 6347c6f
Show file tree
Hide file tree
Showing 24 changed files with 643 additions and 365 deletions.
16 changes: 8 additions & 8 deletions packages/api/scripts/commonObject.sh
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export class ${ObjectCap}Controller {
@ApiHeader({ name: 'integrationId', required: true })
@ApiHeader({ name: 'linkedUserId', required: true })
@ApiQuery({
name: 'remoteData',
name: 'remote_data',
required: false,
type: Boolean,
description:
Expand All @@ -334,7 +334,7 @@ export class ${ObjectCap}Controller {
get${ObjectCap}s(
@Headers('integrationId') integrationId: string,
@Headers('linkedUserId') linkedUserId: string,
@Query('remoteData') remote_data?: boolean,
@Query('remote_data') remote_data?: boolean,
) {
return this.${objectType}Service.get${ObjectCap}s(
integrationId,
Expand All @@ -355,7 +355,7 @@ export class ${ObjectCap}Controller {
description: 'id of the ${objectType} you want to retrieve.',
})
@ApiQuery({
name: 'remoteData',
name: 'remote_data',
required: false,
type: Boolean,
description:
Expand All @@ -365,7 +365,7 @@ export class ${ObjectCap}Controller {
@Get(':id')
get${ObjectCap}(
@Param('id') id: string,
@Query('remoteData') remote_data?: boolean,
@Query('remote_data') remote_data?: boolean,
) {
return this.${objectType}Service.get${ObjectCap}(id, remote_data);
}
Expand All @@ -388,7 +388,7 @@ export class ${ObjectCap}Controller {
example: 'b008e199-eda9-4629-bd41-a01b6195864a',
})
@ApiQuery({
name: 'remoteData',
name: 'remote_data',
required: false,
type: Boolean,
description:
Expand All @@ -401,7 +401,7 @@ export class ${ObjectCap}Controller {
@Body() unified${ObjectCap}Data: Unified${ObjectCap}Input,
@Headers('integrationId') integrationId: string,
@Headers('linkedUserId') linkedUserId: string,
@Query('remoteData') remote_data?: boolean,
@Query('remote_data') remote_data?: boolean,
) {
return this.${objectType}Service.add${ObjectCap}(
unified${ObjectCap}Data,
Expand All @@ -418,7 +418,7 @@ export class ${ObjectCap}Controller {
@ApiHeader({ name: 'integrationId', required: true })
@ApiHeader({ name: 'linkedUserId', required: true })
@ApiQuery({
name: 'remoteData',
name: 'remote_data',
required: false,
type: Boolean,
description:
Expand All @@ -431,7 +431,7 @@ export class ${ObjectCap}Controller {
@Body() unfied${ObjectCap}Data: Unified${ObjectCap}Input[],
@Headers('integrationId') integrationId: string,
@Headers('linkedUserId') linkedUserId: string,
@Query('remoteData') remote_data?: boolean,
@Query('remote_data') remote_data?: boolean,
) {
return this.${objectType}Service.batchAdd${ObjectCap}s(
unfied${ObjectCap}Data,
Expand Down
35 changes: 35 additions & 0 deletions packages/api/src/@core/connections/@utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { PrismaClient } from '@prisma/client';

export type ConnectionMetadata = {
linkedUserId: string;
remoteSource: string;
};

export class ConnectionUtils {
private readonly prisma: PrismaClient;

constructor() {
this.prisma = new PrismaClient();
}

async getConnectionMetadataFromConnectionToken(
token: string,
): Promise<ConnectionMetadata> {
try {
if (!token)
throw new Error('token provided for connection token is invalid');
const res = await this.prisma.connections.findFirst({
where: {
connection_token: token,
},
});
if (!res) throw new Error(`connection not found for token ${token}`);
return {
linkedUserId: res.id_linked_user,
remoteSource: res.provider_slug,
};
} catch (error) {
throw new Error(error);
}
}
}
7 changes: 6 additions & 1 deletion packages/api/src/@core/connections/connections.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ export class ConnectionsController {
@ApiResponse({ status: 200 })
@Get()
async getConnections() {
return await this.prisma.connections.findMany();
return await this.prisma.connections.findMany({
select: {
access_token: false,
refresh_token: false,
},
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,6 @@ export class CrmConnectionsService {
zohoLocation?: string,
) {
try {
const job_resp_create = await this.prisma.events.create({
data: {
id_event: uuidv4(),
status: 'initialized',
type: 'connection.created',
method: 'GET',
url: '/oauth/callback',
provider: providerName.toLowerCase(),
direction: '0',
timestamp: new Date(),
id_linked_user: linkedUserId,
},
});
if (!code) {
throw new NotFoundError(`no ${providerName} code found, found ${code}`);
}
Expand All @@ -72,19 +59,24 @@ export class CrmConnectionsService {
};
const data: Connection = await service.handleCallback(callbackOpts);

await this.prisma.events.update({
where: {
id_event: job_resp_create.id_event,
},
const event = await this.prisma.events.create({
data: {
id_event: uuidv4(),
status: 'success',
type: 'connection.created',
method: 'GET',
url: '/oauth/callback',
provider: providerName.toLowerCase(),
direction: '0',
timestamp: new Date(),
id_linked_user: linkedUserId,
},
});
await this.webhook.handleWebhook(
data,
'connection.created',
projectId,
job_resp_create.id_event,
event.id_event,
);
} catch (error) {
handleServiceError(error, this.logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export class HubspotConnectionService implements ICrmConnectionService {
const data: HubspotOAuthResponse = res.data;
// save tokens for this customer inside our db
let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
// Update existing connection
db_res = await this.prisma.connections.update({
Expand All @@ -80,6 +82,7 @@ export class HubspotConnectionService implements ICrmConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'hubspot',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class PipedriveConnectionService implements ICrmConnectionService {
const data: PipeDriveOAuthResponse = res.data;
this.logger.log('OAuth credentials : pipedrive ');
let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
Expand All @@ -79,6 +80,7 @@ export class PipedriveConnectionService implements ICrmConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'pipedrive',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class ZendeskConnectionService implements ICrmConnectionService {
this.logger.log('OAuth credentials : zendesk ' + JSON.stringify(data));

let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
Expand All @@ -81,6 +82,7 @@ export class ZendeskConnectionService implements ICrmConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'zendesk',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export class ZohoConnectionService implements ICrmConnectionService {
const data: ZohoOAuthResponse = res.data;
this.logger.log('OAuth credentials : zoho ' + JSON.stringify(data));
let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
Expand All @@ -90,6 +91,7 @@ export class ZohoConnectionService implements ICrmConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'zoho',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class FrontConnectionService implements ITicketingConnectionService {
);

let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
Expand All @@ -85,6 +86,7 @@ export class FrontConnectionService implements ITicketingConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'front',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class GithubConnectionService implements ITicketingConnectionService {
);

let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
Expand All @@ -82,6 +83,7 @@ export class GithubConnectionService implements ITicketingConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'github',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,6 @@ export class TicketingConnectionsService {
zohoLocation?: string,
) {
try {
const job_resp_create = await this.prisma.events.create({
data: {
id_event: uuidv4(),
status: 'initialized',
type: 'connection.created',
method: 'GET',
url: '/oauth/callback',
provider: providerName.toLowerCase(),
direction: '0',
timestamp: new Date(),
id_linked_user: linkedUserId,
},
});
const serviceName = providerName.toLowerCase();
const service = this.serviceRegistry.getService(serviceName);

Expand All @@ -66,19 +53,25 @@ export class TicketingConnectionsService {
location: zohoLocation || null,
};
const data: Connection = await service.handleCallback(callbackOpts);
await this.prisma.events.update({
where: {
id_event: job_resp_create.id_event,
},

const event = await this.prisma.events.create({
data: {
id_event: uuidv4(),
status: 'success',
type: 'connection.created',
method: 'GET',
url: '/oauth/callback',
provider: providerName.toLowerCase(),
direction: '0',
timestamp: new Date(),
id_linked_user: linkedUserId,
},
});
await this.webhook.handleWebhook(
data,
'connection.created',
projectId,
job_resp_create.id_event,
event.id_event,
);
} catch (error) {
handleServiceError(error, this.logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class ZendeskConnectionService implements ITicketingConnectionService {
);

let db_res;
const connection_token = uuidv4();

if (isNotUnique) {
db_res = await this.prisma.connections.update({
Expand All @@ -81,6 +82,7 @@ export class ZendeskConnectionService implements ITicketingConnectionService {
db_res = await this.prisma.connections.create({
data: {
id_connection: uuidv4(),
connection_token: connection_token,
provider_slug: 'zendesk_tcg',
token_type: 'oauth',
access_token: this.cryptoService.encrypt(data.access_token),
Expand Down
1 change: 0 additions & 1 deletion packages/api/src/@core/utils/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import axios, { AxiosError } from 'axios';
import { Prisma } from '@prisma/client';
import { TargetObject } from './types';
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';
import { PinoLogger } from 'nestjs-pino';

type ServiceError = AxiosError | PrismaClientKnownRequestError | Error;

Expand Down
Loading

0 comments on commit 6347c6f

Please sign in to comment.