From 672cc4c60c1e17d7b63bcfe6c430c098e0017169 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Tue, 19 Oct 2021 16:29:37 +0200 Subject: [PATCH] feat: Serve static assets of apps --- packages/backend/src/app.ts | 3 ++ .../src/apps/flickr/assets/favicon.svg | 5 ++++ .../src/apps/flickr/{info.json => info.ts} | 9 ++++-- .../src/apps/twitch/assets/favicon.svg | 4 +++ .../src/apps/twitch/{info.json => info.ts} | 9 ++++-- .../src/apps/twitter/assets/favicon.svg | 4 +++ .../src/apps/twitter/{info.json => info.ts} | 9 ++++-- packages/backend/src/config/app.ts | 10 ++++++- packages/backend/src/config/cors-options.ts | 2 +- .../src/graphql/queries/get-connected-apps.ts | 2 +- .../backend/src/helpers/app-assets-handler.ts | 15 ++++++++++ packages/backend/src/models/app.ts | 28 +++++++++++-------- packages/backend/src/types/app-info.ts | 14 ++++++++++ .../src/types/authentication-step-field.ts | 10 +++++++ .../backend/src/types/authentication-step.ts | 10 +++++++ packages/backend/src/types/field.d.ts | 2 +- packages/web/src/components/AppIcon/index.tsx | 5 ++-- 17 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 packages/backend/src/apps/flickr/assets/favicon.svg rename packages/backend/src/apps/flickr/{info.json => info.ts} (92%) create mode 100644 packages/backend/src/apps/twitch/assets/favicon.svg rename packages/backend/src/apps/twitch/{info.json => info.ts} (84%) create mode 100644 packages/backend/src/apps/twitter/assets/favicon.svg rename packages/backend/src/apps/twitter/{info.json => info.ts} (92%) create mode 100644 packages/backend/src/helpers/app-assets-handler.ts create mode 100644 packages/backend/src/types/app-info.ts create mode 100644 packages/backend/src/types/authentication-step-field.ts create mode 100644 packages/backend/src/types/authentication-step.ts diff --git a/packages/backend/src/app.ts b/packages/backend/src/app.ts index 915a95e4..d2306a04 100644 --- a/packages/backend/src/app.ts +++ b/packages/backend/src/app.ts @@ -6,6 +6,7 @@ import corsOptions from './config/cors-options'; import graphQLInstance from './helpers/graphql-instance'; import logger from './helpers/logger'; import morgan from './helpers/morgan'; +import appAssetsHandler from './helpers/app-assets-handler'; import errorHandler from './helpers/error-handler'; import './config/database'; import authentication from './helpers/authentication'; @@ -13,6 +14,8 @@ import authentication from './helpers/authentication'; const app = express(); const port = appConfig.port; +appAssetsHandler(app) + app.use(morgan); app.use(express.json()); app.use(express.urlencoded({ extended: false })); diff --git a/packages/backend/src/apps/flickr/assets/favicon.svg b/packages/backend/src/apps/flickr/assets/favicon.svg new file mode 100644 index 00000000..f8499a7a --- /dev/null +++ b/packages/backend/src/apps/flickr/assets/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/backend/src/apps/flickr/info.json b/packages/backend/src/apps/flickr/info.ts similarity index 92% rename from packages/backend/src/apps/flickr/info.json rename to packages/backend/src/apps/flickr/info.ts index 84ef5122..cead0766 100644 --- a/packages/backend/src/apps/flickr/info.json +++ b/packages/backend/src/apps/flickr/info.ts @@ -1,7 +1,10 @@ -{ +import appInfoType from '../../types/app-info'; +import appConfig from '../../config/app'; + +const appInfo: appInfoType = { "name": "Flickr", "key": "flickr", - "iconUrl": "https://automatisch.io/apps/flickr.png", + "iconUrl": `${appConfig.baseUrl}/apps/flickr/assets/favicon.svg`, "docUrl": "https://automatisch.io/docs/flickr", "primaryColor": "000000", "fields": [ @@ -113,3 +116,5 @@ } ] } + +export default appInfo; diff --git a/packages/backend/src/apps/twitch/assets/favicon.svg b/packages/backend/src/apps/twitch/assets/favicon.svg new file mode 100644 index 00000000..8adbef1a --- /dev/null +++ b/packages/backend/src/apps/twitch/assets/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/backend/src/apps/twitch/info.json b/packages/backend/src/apps/twitch/info.ts similarity index 84% rename from packages/backend/src/apps/twitch/info.json rename to packages/backend/src/apps/twitch/info.ts index f96966ab..b6e57b81 100644 --- a/packages/backend/src/apps/twitch/info.json +++ b/packages/backend/src/apps/twitch/info.ts @@ -1,7 +1,10 @@ -{ +import appInfoType from '../../types/app-info'; +import appConfig from '../../config/app'; + +const appInfo: appInfoType = { "name": "Twitch", "key": "twitch", - "iconUrl": "https://automatisch.io/apps/twitch.png", + "iconUrl": `${appConfig.baseUrl}/apps/twitch/assets/favicon.svg`, "docUrl": "https://automatisch.io/docs/twitch", "primaryColor": "6441a5", "fields": [ @@ -43,3 +46,5 @@ } ] } + +export default appInfo; diff --git a/packages/backend/src/apps/twitter/assets/favicon.svg b/packages/backend/src/apps/twitter/assets/favicon.svg new file mode 100644 index 00000000..752cdc8d --- /dev/null +++ b/packages/backend/src/apps/twitter/assets/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/backend/src/apps/twitter/info.json b/packages/backend/src/apps/twitter/info.ts similarity index 92% rename from packages/backend/src/apps/twitter/info.json rename to packages/backend/src/apps/twitter/info.ts index d6801671..6ac965f3 100644 --- a/packages/backend/src/apps/twitter/info.json +++ b/packages/backend/src/apps/twitter/info.ts @@ -1,7 +1,10 @@ -{ +import appInfoType from '../../types/app-info'; +import appConfig from '../../config/app'; + +const appInfo: appInfoType = { "name": "Twitter", "key": "twitter", - "iconUrl": "https://automatisch.io/apps/twitter.png", + "iconUrl": `${appConfig.baseUrl}/apps/twitter/assets/favicon.svg`, "docUrl": "https://automatisch.io/docs/twitter", "primaryColor": "2DAAE1", "fields": [ @@ -113,3 +116,5 @@ } ] } + +export default appInfo; diff --git a/packages/backend/src/config/app.ts b/packages/backend/src/config/app.ts index 8f24a61d..0453c2c6 100644 --- a/packages/backend/src/config/app.ts +++ b/packages/backend/src/config/app.ts @@ -11,7 +11,9 @@ type AppConfig = { postgresPort: number, postgresHost: string, postgresUsername: string, - postgresPassword: string + postgresPassword: string, + baseUrl?: string + webAppUrl?: string } const appConfig: AppConfig = { @@ -27,4 +29,10 @@ const appConfig: AppConfig = { postgresPassword: process.env.POSTGRESS_PASSWORD, } +const webAppUrl = `${appConfig.protocol}://${appConfig.host}:${appConfig.corsPort}`; +appConfig.webAppUrl = webAppUrl; + +const baseUrl = `${appConfig.protocol}://${appConfig.host}:${appConfig.port}`; +appConfig.baseUrl = baseUrl; + export default appConfig; diff --git a/packages/backend/src/config/cors-options.ts b/packages/backend/src/config/cors-options.ts index 92262a8a..5ebc5c2c 100644 --- a/packages/backend/src/config/cors-options.ts +++ b/packages/backend/src/config/cors-options.ts @@ -1,7 +1,7 @@ import appConfig from './app' const corsOptions = { - origin: `${appConfig.protocol}://${appConfig.host}:${appConfig.corsPort}`, + origin: appConfig.webAppUrl, methods: 'POST', credentials: true, optionsSuccessStatus: 200, diff --git a/packages/backend/src/graphql/queries/get-connected-apps.ts b/packages/backend/src/graphql/queries/get-connected-apps.ts index e0036ce1..1d6c511b 100644 --- a/packages/backend/src/graphql/queries/get-connected-apps.ts +++ b/packages/backend/src/graphql/queries/get-connected-apps.ts @@ -9,7 +9,7 @@ type Params = { } const getConnectedAppsResolver = async (params: Params, req: RequestWithCurrentUser) => { - let apps = App.findAll(params.name) + let apps = await App.findAll(params.name) const connections = await Connection.query() .select('connections.key') diff --git a/packages/backend/src/helpers/app-assets-handler.ts b/packages/backend/src/helpers/app-assets-handler.ts new file mode 100644 index 00000000..7c2e0b15 --- /dev/null +++ b/packages/backend/src/helpers/app-assets-handler.ts @@ -0,0 +1,15 @@ +import express, { Application } from 'express'; +import App from '../models/app'; + +const appAssetsHandler = async (app: Application) => { + const appNames = App.list; + + appNames.forEach(appName => { + app.use( + `/apps/${appName}/assets/favicon.svg`, + express.static(`src/apps/${appName}/assets/favicon.svg`) + ) + }) +} + +export default appAssetsHandler; diff --git a/packages/backend/src/models/app.ts b/packages/backend/src/models/app.ts index ce1dc1e1..267e840c 100644 --- a/packages/backend/src/models/app.ts +++ b/packages/backend/src/models/app.ts @@ -4,22 +4,28 @@ class App { static folderPath = __dirname + '/../apps'; static list = fs.readdirSync(this.folderPath); - static findAll(name?: string): object[] { - if(!name) return this.list.map((name) => this.findOneByName(name)); + static async findAll(name?: string): Promise { + let appList; - return this.list - .filter((app) => app.includes(name.toLowerCase())) - .map((name) => this.findOneByName(name)); + if(!name) { + appList = this.list.map(async (name) => await this.findOneByName(name)); + } else { + appList = this.list + .filter((app) => app.includes(name.toLowerCase())) + .map(async (name) => await this.findOneByName(name)); + } + + return Promise.all(appList) } - static findOneByName(name: string): object { - const rawAppData = fs.readFileSync(this.folderPath + `/${name}/info.json`, 'utf-8'); - return JSON.parse(rawAppData); + static async findOneByName(name: string): Promise { + const rawAppData = (await import(`../apps/${name}/info`)).default; + return rawAppData; } - static findOneByKey(key: string): object { - const rawAppData = fs.readFileSync(this.folderPath + `/${key}/info.json`, 'utf-8'); - return JSON.parse(rawAppData); + static async findOneByKey(key: string): Promise { + const rawAppData = (await import(`../apps/${key}/info`)).default; + return rawAppData; } } diff --git a/packages/backend/src/types/app-info.ts b/packages/backend/src/types/app-info.ts new file mode 100644 index 00000000..a7584557 --- /dev/null +++ b/packages/backend/src/types/app-info.ts @@ -0,0 +1,14 @@ +import FieldType from './field'; +import AuthenticationStepType from './authentication-step'; + +type AppInfo = { + name: string, + key: string, + iconUrl: string, + docUrl: string, + primaryColor: string, + fields: FieldType[], + authenticationSteps?: AuthenticationStepType[] +} + +export default AppInfo; diff --git a/packages/backend/src/types/authentication-step-field.ts b/packages/backend/src/types/authentication-step-field.ts new file mode 100644 index 00000000..e5d2e78c --- /dev/null +++ b/packages/backend/src/types/authentication-step-field.ts @@ -0,0 +1,10 @@ +type AuthenticationStepField = { + name: string, + value: string | null, + fields?: { + name: string, + value: string | null + }[] +} + +export default AuthenticationStepField; diff --git a/packages/backend/src/types/authentication-step.ts b/packages/backend/src/types/authentication-step.ts new file mode 100644 index 00000000..824405ee --- /dev/null +++ b/packages/backend/src/types/authentication-step.ts @@ -0,0 +1,10 @@ +import AuthenticationStepField from '../types/authentication-step-field'; + +type AuthenticationStep = { + step: number, + type: string, + name: string, + fields: AuthenticationStepField[]; +} + +export default AuthenticationStep; diff --git a/packages/backend/src/types/field.d.ts b/packages/backend/src/types/field.d.ts index b7d3f62e..53e0d378 100644 --- a/packages/backend/src/types/field.d.ts +++ b/packages/backend/src/types/field.d.ts @@ -5,7 +5,7 @@ type Field = { required: boolean, readOnly: boolean, value: string, - placeholder: string, + placeholder: string | null, description: string, docUrl: string, clickToCopy: boolean diff --git a/packages/web/src/components/AppIcon/index.tsx b/packages/web/src/components/AppIcon/index.tsx index feb19ac9..46525f86 100644 --- a/packages/web/src/components/AppIcon/index.tsx +++ b/packages/web/src/components/AppIcon/index.tsx @@ -7,8 +7,9 @@ type AppIconProps = { }; export default function AppIcon(props: AppIconProps) { - const { color, name, url } = props; - + const { name, url } = props; + const color = url ? 'white' : props.color + return ( );