Skip to content

Commit

Permalink
Fix: Spec now handles OAuth2 (#126)
Browse files Browse the repository at this point in the history
* Feat: Spec now handles OAuth independently

* Fix: linting
  • Loading branch information
harshithmullapudi authored Jul 7, 2023
1 parent f9b9845 commit af77420
Show file tree
Hide file tree
Showing 40 changed files with 571 additions and 314 deletions.
12 changes: 2 additions & 10 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ENGINE_VERSION=0.1.3-alpha
ENGINE_VERSION=0.1.4-alpha

# POSTGRES
POSTGRES_USER=docker
Expand Down Expand Up @@ -30,12 +30,4 @@ BACKEND_HOST=http://localhost:3000

BACKEND_URL=http://server:3000

SUPERTOKEN_CONNECTION_URI=https://try.supertokens.com


# For creating default Users
USER_PASSWORD=
USER_EMAIL=
USER_FIRSTNAME=
USER_LASTNAME=
CREATE_DEFAULT_USER=false
SUPERTOKEN_CONNECTION_URI=http://supertokens:3567
10 changes: 2 additions & 8 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ services:
- 5432:5432
networks:
- poozle
volumes:
- postgres-data:/var/lib/postgresql/data
restart: unless-stopped

server:
Expand All @@ -31,12 +33,6 @@ services:
- JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET}
- PORT=${PORT}
- SUPERTOKEN_CONNECTION_URI=${SUPERTOKEN_CONNECTION_URI}
# Default User
- USER_PASSWORD=${USER_PASSWORD}
- USER_EMAIL=${USER_EMAIL}
- USER_FIRSTNAME=${USER_FIRSTNAME}
- USER_LASTNAME=${USER_LASTNAME}
- CREATE_DEFAULT_USER=${CREATE_DEFAULT_USER}

webapp:
image: poozlehq/engine-webapp:${ENGINE_VERSION}
Expand All @@ -56,8 +52,6 @@ services:
image: registry.supertokens.io/supertokens/supertokens-postgresql:5.0
depends_on:
- db
ports:
- 3567:3567
environment:
POSTGRESQL_CONNECTION_URI: ${SUPERTOKEN_DATABASE_URL}
networks:
Expand Down
2 changes: 1 addition & 1 deletion engine-idk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@poozle/engine-idk",
"version": "0.1.6",
"version": "0.1.8",
"description": "Used to develop integrations for Poozle",
"license": "MIT",
"author": "Poozle <support@poozle.in>",
Expand Down
11 changes: 3 additions & 8 deletions engine-idk/src/bases/base_integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
SpecificationResponse,
AuthHeaderResponse,
RunResponse,
AuthSpecificationOAuth,
AuthSpecificationGeneric,
Params,
} from 'types/integration';

Expand All @@ -22,10 +20,7 @@ export class BaseIntegration implements BaseIntegrationInterface {
*/
async spec(): SpecificationResponse {
return {
authSupported: [],
authSpecification: {},
supportedFilters: [],
supportedSortBy: [],
auth_specification: {},
};
}

Expand All @@ -50,7 +45,7 @@ export class BaseIntegration implements BaseIntegrationInterface {

if (config.authType === 'OAuth2') {
const spec = await this.spec();
const specification = spec.authSpecification['OAuth2'] as AuthSpecificationOAuth;
const specification = spec.auth_specification['OAuth2'];
headers = specification.headers ?? {};
token = await getAccessToken(
interpolateString(specification.token_url as string, config),
Expand All @@ -62,7 +57,7 @@ export class BaseIntegration implements BaseIntegrationInterface {
} else {
const type = config.authType;
const spec = await this.spec();
const specification = spec.authSpecification[type] as AuthSpecificationGeneric;
const specification = spec.auth_specification[type];
headers = specification.headers ?? {};
}

Expand Down
20 changes: 5 additions & 15 deletions engine-idk/src/types/integration.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
/** Copyright (c) 2023, Poozle, all rights reserved. **/

export interface AuthSpecificationGeneric {
inputSpecification?: {
export interface GenericInputSpecification {
input_specification: {
type: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
properties: Record<string, any>;
};
headers?: Record<string, string>;
}

export interface AuthSpecificationOAuth {
export interface AuthSpecification extends GenericInputSpecification {
// Params that are directly supported by simple-oauth2
token_url?: string;
auth_mode?: string;
authorization_url?: string;
authorization_params?: Record<string, string>;
token_params?: Record<string, string>;
headers?: Record<string, string>;
// Needed to store
inputSpecification?: {
type: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
properties: Record<string, any>;
};
}

// Generic holder of config for integration
Expand All @@ -35,12 +28,9 @@ export interface CheckResponseType {
}
export type CheckResponse = Promise<CheckResponseType>;

export type AuthSupported = string[];
export interface Specification {
authSupported: AuthSupported;
authSpecification: Record<string, AuthSpecificationGeneric | AuthSpecificationOAuth>;
supportedFilters: string[];
supportedSortBy: string[];
auth_specification: Record<string, AuthSpecification>;
other_inputs?: GenericInputSpecification;
}
export type SpecificationResponse = Promise<Specification>;

Expand Down
10 changes: 6 additions & 4 deletions engine-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "engine-server",
"version": "0.1.3-alpha",
"version": "0.1.4-alpha",
"description": "Poozle engine",
"author": "Poozle",
"license": "MIT",
Expand All @@ -25,8 +25,8 @@
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/src/main",
"start:migrate:prod": "yarn migrate:deploy && yarn seed && node dist/src/main",
"start:prod": "node dist/main",
"start:migrate:prod": "yarn migrate:deploy && yarn seed && node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"migrate:dev": "prisma migrate dev --preview-feature",
"migrate:dev:create": "prisma migrate dev --create-only --preview-feature",
Expand All @@ -44,7 +44,7 @@
"test:e2e": "jest --config ./test/jest-e2e.json",
"start:db": "npm run migrate:up && npm run prisma:generate && npm run seed",
"seed": "prisma db seed",
"create-default-user": "ts-node prisma/seeds/user.ts",
"create-user": "ts-node prisma/seeds/user.ts",
"postinstall": "npm run prisma:generate"
},
"dependencies": {
Expand Down Expand Up @@ -72,6 +72,7 @@
"nestjs-prisma": "0.20.0",
"passport": "0.6.0",
"passport-jwt": "4.0.1",
"prompt-sync": "^4.2.0",
"reflect-metadata": "0.1.13",
"rimraf": "4.1.1",
"rxjs": "7.8.0",
Expand All @@ -90,6 +91,7 @@
"@types/jest": "28.1.6",
"@types/node": "^18.11.18",
"@types/passport-jwt": "^3.0.8",
"@types/prompt-sync": "^4.2.0",
"@types/simple-oauth2": "^5.0.4",
"@types/supertest": "2.0.12",
"@typescript-eslint/eslint-plugin": "5.48.2",
Expand Down
48 changes: 41 additions & 7 deletions engine-server/prisma/seeds/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,48 @@

import { PrismaClient } from '@prisma/client';
import axios from 'axios';
// import axios from 'axios';
import * as promptSync from 'prompt-sync';

const prisma = new PrismaClient();

const prompt = promptSync();

// eslint-disable-next-line prefer-const
let retryTimes = 0;

async function waitForServerResponse(): Promise<boolean> {
const healthUrl = `${process.env.BACKEND_HOST}/health`;

while (retryTimes < 10) {
try {
const response = await axios.get(healthUrl);
if (response.status === 200) {
console.log('Server is healthy!');
return true;
}
} catch (error) {
console.log('Server is still starting up. Retrying in 2 second...');
await new Promise((resolve) => setTimeout(resolve, 2000));
}
}

return false;
}

async function main() {
const email = process.env.USER_EMAIL;
const password = process.env.USER_PASSWORD;
const createDefaultUser = process.env.CREATE_DEFAULT_USER;
// Wait for server to be up and running
const status = await waitForServerResponse();

if (!status) {
console.log('Server was never up');
console.log('Failed creating user');
return;
}

const email = prompt('Enter email: ');
const password = prompt('Enter password: ');
const firstName = prompt('Enter firstname: ');
const lastName = prompt('Enter lastname: ');

const users = await prisma.user.findMany({
where: {
Expand All @@ -22,7 +56,7 @@ async function main() {
console.log('User already exist');
}

if (createDefaultUser === 'true' && email && password && users.length === 0) {
if (email && password && users.length === 0) {
try {
const response = await axios.post(
`${process.env.BACKEND_HOST}/auth/signup`,
Expand Down Expand Up @@ -51,8 +85,8 @@ async function main() {
await axios.post(
`${process.env.BACKEND_HOST}/v1/user`,
{
firstname: process.env.USER_FIRSTNAME,
lastname: process.env.USER_LASTNAME,
firstname: firstName,
lastname: lastName,
email,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
IntegrationDefinitionCreateBody,
IntegrationDefinitionRequestIdBody,
IntegrationDefinitionRequestWorkspaceIdBody,
IntegrationDefinitionUpdateBody,
} from './integration_definition.interface';
import { IntegrationDefinitionService } from './integration_definition.service';

Expand All @@ -43,11 +44,24 @@ export class IntegrationDefinitionController {
);
}

@Post(':integrationDefinitionId')
async updateIntegrationDefinition(
@Param()
integrationDefinitionRequestIdBody: IntegrationDefinitionRequestIdBody,
@Body()
integrationDefinitionUpdateBody: IntegrationDefinitionUpdateBody,
) {
return await this.integrationDefinitionService.updateIntegrationDefinition(
integrationDefinitionUpdateBody,
integrationDefinitionRequestIdBody.integrationDefinitionId,
);
}

@Get(':integrationDefinitionId/spec')
async getSpecForIntegrationDefinition(
@Param()
integrationDefinitionRequestIdBody: IntegrationDefinitionRequestIdBody,
@Query()
@Body()
integrationDefinitionRequestWorkspaceIdBody: IntegrationDefinitionRequestWorkspaceIdBody,
): Promise<Specification> {
return await this.integrationDefinitionService.getSpecForIntegrationDefinition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { IntegrationType } from '@prisma/client';
import { Transform, Type } from 'class-transformer';
import { IsArray, IsOptional, IsString } from 'class-validator';

import { IntegrationDefinition } from '@@generated/integrationDefinition/entities';

export class IntegrationDefinitionRequestWorkspaceIdBody {
@IsString()
workspaceId: string;
Expand Down Expand Up @@ -38,3 +40,17 @@ export class IntegrationDefinitionCreateBody {
@IsString()
workspaceId: string;
}

export class IntegrationDefinitionUpdateBody {
@IsString()
sourceUrl: string;

@IsString()
version: string;
}

export class IntegrationDefinitionResponse extends IntegrationDefinition {
isLatest: boolean;
latestVersion: string;
latestVersionSource: string;
}
Loading

0 comments on commit af77420

Please sign in to comment.