Secure connexion between TinyBird and webhookResponseGraph (#7913)
TLDR: Secure connexion between tinybird and twenty using jwt when accessing datasource from tinybird. Solves: https://github.com/twentyhq/private-issues/issues/73 In order to test: 1. Set ANALYTICS_ENABLED to true 2. Set TINYBIRD_JWT_TOKEN to the ADMIN token from the workspace twenty_analytics_playground 3. Set TINYBIRD_JWT_TOKEN to the datasource or your admin token from the workspace twenty_analytics_playground 4. Create a Webhook in twenty and set wich events it needs to track 5. Run twenty-worker in order to make the webhooks work. 6. Do your tasks in order to populate the data 7. Enter to settings> webhook>your webhook and the statistics section should be displayed. --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
edf4ae084b
commit
373926b895
@ -1,6 +1,8 @@
|
||||
import { HttpModule } from '@nestjs/axios';
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { JwtModule } from 'src/engine/core-modules/jwt/jwt.module';
|
||||
|
||||
import { AnalyticsResolver } from './analytics.resolver';
|
||||
import { AnalyticsService } from './analytics.service';
|
||||
|
||||
@ -9,6 +11,7 @@ const TINYBIRD_BASE_URL = 'https://api.eu-central-1.aws.tinybird.co/v0';
|
||||
@Module({
|
||||
providers: [AnalyticsResolver, AnalyticsService],
|
||||
imports: [
|
||||
JwtModule,
|
||||
HttpModule.register({
|
||||
baseURL: TINYBIRD_BASE_URL,
|
||||
}),
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||
|
||||
import { AnalyticsResolver } from './analytics.resolver';
|
||||
import { AnalyticsService } from './analytics.service';
|
||||
@ -13,13 +10,8 @@ describe('AnalyticsResolver', () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
AnalyticsResolver,
|
||||
AnalyticsService,
|
||||
{
|
||||
provide: EnvironmentService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: HttpService,
|
||||
provide: AnalyticsService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||
@ -13,10 +12,7 @@ import { CreateAnalyticsInput } from './dtos/create-analytics.input';
|
||||
|
||||
@Resolver(() => Analytics)
|
||||
export class AnalyticsResolver {
|
||||
constructor(
|
||||
private readonly analyticsService: AnalyticsService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
) {}
|
||||
constructor(private readonly analyticsService: AnalyticsService) {}
|
||||
|
||||
@Mutation(() => Analytics)
|
||||
track(
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||
|
||||
import { AnalyticsService } from './analytics.service';
|
||||
|
||||
@ -16,6 +17,10 @@ describe('AnalyticsService', () => {
|
||||
provide: EnvironmentService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: JwtWrapperService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: HttpService,
|
||||
useValue: {},
|
||||
|
||||
@ -4,6 +4,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||
import { AxiosRequestConfig } from 'axios';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
|
||||
|
||||
type CreateEventInput = {
|
||||
action: string;
|
||||
@ -16,6 +17,7 @@ export class AnalyticsService {
|
||||
private readonly defaultDatasource = 'event';
|
||||
|
||||
constructor(
|
||||
private readonly jwtWrapperService: JwtWrapperService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly httpService: HttpService,
|
||||
) {}
|
||||
@ -58,7 +60,7 @@ export class AnalyticsService {
|
||||
const config: AxiosRequestConfig = {
|
||||
headers: {
|
||||
Authorization:
|
||||
'Bearer ' + this.environmentService.get('TINYBIRD_TOKEN'),
|
||||
'Bearer ' + this.environmentService.get('TINYBIRD_INGEST_TOKEN'),
|
||||
},
|
||||
};
|
||||
|
||||
@ -86,4 +88,25 @@ export class AnalyticsService {
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async generateWorkspaceJwt(workspaceId: string | undefined) {
|
||||
const pipeId = 't_b49e0fe60f9e438eae81cb31c5260df2'; // refactor this pass as params
|
||||
//perhaps a constant of name:pipeId??? better typing in this func^
|
||||
const payload = {
|
||||
name: 'my_demo_jwt',
|
||||
workspace_id: this.environmentService.get('TINYBIRD_WORKSPACE_UUID'),
|
||||
scopes: [
|
||||
{
|
||||
type: 'PIPES:READ',
|
||||
resource: pipeId,
|
||||
fixed_params: { workspaceId: workspaceId },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return this.jwtWrapperService.sign(payload, {
|
||||
secret: this.environmentService.get('TINYBIRD_GENERATE_JWT_TOKEN'),
|
||||
expiresIn: '7d',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user