From 2976b3550573ea66cc388c6d831bb30e1014dc4d Mon Sep 17 00:00:00 2001 From: Katalina Okano Date: Fri, 18 Dec 2020 13:17:49 -0500 Subject: [PATCH] chore(api): re-add roleypoly creation gated by root --- .../handlers/create-roleypoly-data.ts | 160 ++++++++++-------- src/backend-worker/index.ts | 35 +++- src/backend-worker/utils/api-tools.ts | 20 ++- 3 files changed, 135 insertions(+), 80 deletions(-) diff --git a/src/backend-worker/handlers/create-roleypoly-data.ts b/src/backend-worker/handlers/create-roleypoly-data.ts index e4394ed..1d32409 100644 --- a/src/backend-worker/handlers/create-roleypoly-data.ts +++ b/src/backend-worker/handlers/create-roleypoly-data.ts @@ -1,80 +1,94 @@ import KSUID from 'ksuid'; import { CategoryType, Features, GuildData as GuildDataT } from 'roleypoly/common/types'; -import { respond } from '../utils/api-tools'; +import { onlyRootUsers, respond } from '../utils/api-tools'; import { GuildData } from '../utils/kv'; // Temporary use. -export const CreateRoleypolyData = async (request: Request): Promise => { - const data: GuildDataT = { - id: '386659935687147521', - message: - 'Hey, this is kind of a demo setup so features/use cases can be shown off.\n\nThanks for using Roleypoly <3', - features: Features.Preview, - categories: [ - { - id: KSUID.randomSync().string, - name: 'Demo Roles', - type: CategoryType.Multi, - hidden: false, - position: 0, - roles: [ - '557825026406088717', - '557824994269200384', - '557824893241131029', - '557812915386843170', - '557812901717737472', - '557812805546541066', - ], - }, - { - id: KSUID.randomSync().string, - name: 'Colors', - type: CategoryType.Single, - hidden: false, - position: 1, - roles: ['394060232893923349', '394060145799331851', '394060192846839809'], - }, - { - id: KSUID.randomSync().string, - name: 'Test Roles', - type: CategoryType.Multi, - hidden: false, - position: 5, - roles: ['558104828216213505', '558103534453653514', '558297233582194728'], - }, - { - id: KSUID.randomSync().string, - name: 'Region', - type: CategoryType.Multi, - hidden: false, - position: 3, - roles: [ - '397296181803483136', - '397296137066774529', - '397296218809827329', - '397296267283267605', - ], - }, - { - id: KSUID.randomSync().string, - name: 'Opt-in Channels', - type: CategoryType.Multi, - hidden: false, - position: 4, - roles: ['414514823959674890', '764230661904007219'], - }, - { - id: KSUID.randomSync().string, - name: 'Pronouns', - type: CategoryType.Multi, - hidden: false, - position: 2, - roles: ['485916566790340608', '485916566941335583', '485916566311927808'], - }, - ], - }; +export const CreateRoleypolyData = onlyRootUsers( + async (request: Request): Promise => { + const data: GuildDataT = { + id: '386659935687147521', + message: + 'Hey, this is kind of a demo setup so features/use cases can be shown off.\n\nThanks for using Roleypoly <3', + features: Features.Preview, + categories: [ + { + id: KSUID.randomSync().string, + name: 'Demo Roles', + type: CategoryType.Multi, + hidden: false, + position: 0, + roles: [ + '557825026406088717', + '557824994269200384', + '557824893241131029', + '557812915386843170', + '557812901717737472', + '557812805546541066', + ], + }, + { + id: KSUID.randomSync().string, + name: 'Colors', + type: CategoryType.Single, + hidden: false, + position: 1, + roles: [ + '394060232893923349', + '394060145799331851', + '394060192846839809', + ], + }, + { + id: KSUID.randomSync().string, + name: 'Test Roles', + type: CategoryType.Multi, + hidden: false, + position: 5, + roles: [ + '558104828216213505', + '558103534453653514', + '558297233582194728', + ], + }, + { + id: KSUID.randomSync().string, + name: 'Region', + type: CategoryType.Multi, + hidden: false, + position: 3, + roles: [ + '397296181803483136', + '397296137066774529', + '397296218809827329', + '397296267283267605', + ], + }, + { + id: KSUID.randomSync().string, + name: 'Opt-in Channels', + type: CategoryType.Multi, + hidden: false, + position: 4, + roles: ['414514823959674890', '764230661904007219'], + }, + { + id: KSUID.randomSync().string, + name: 'Pronouns', + type: CategoryType.Multi, + hidden: false, + position: 2, + roles: [ + '485916566790340608', + '485916566941335583', + '485916566311927808', + ], + }, + ], + }; - await GuildData.put(data.id, data); + await GuildData.put(data.id, data); - return respond({ ok: true }); -}; + return respond({ ok: true }); + } +); diff --git a/src/backend-worker/index.ts b/src/backend-worker/index.ts index ad497f4..a8fbd5c 100644 --- a/src/backend-worker/index.ts +++ b/src/backend-worker/index.ts @@ -1,4 +1,5 @@ import { BotJoin } from './handlers/bot-join'; +import { CreateRoleypolyData } from './handlers/create-roleypoly-data'; import { GetPickerData } from './handlers/get-picker-data'; import { GetSession } from './handlers/get-session'; import { GetSlug } from './handlers/get-slug'; @@ -6,20 +7,28 @@ import { LoginBounce } from './handlers/login-bounce'; import { LoginCallback } from './handlers/login-callback'; import { RevokeSession } from './handlers/revoke-session'; import { Router } from './router'; +import { respond } from './utils/api-tools'; +import { uiPublicURI } from './utils/config'; const router = new Router(); -router.addFallback('root', () => { - return new Response('hello!!'); -}); - +// OAuth router.add('GET', 'bot-join', BotJoin); router.add('GET', 'login-bounce', LoginBounce); router.add('GET', 'login-callback', LoginCallback); -router.add('POST', 'revoke-session', RevokeSession); + +// Session router.add('GET', 'get-session', GetSession); +router.add('POST', 'revoke-session', RevokeSession); + +// Main biz logic router.add('GET', 'get-slug', GetSlug); router.add('GET', 'get-picker-data', GetPickerData); + +// Root users only +router.add('GET', 'x-create-roleypoly-data', CreateRoleypolyData); + +// Tester Routes router.add('GET', 'x-headers', (request) => { const headers: { [x: string]: string } = {}; @@ -29,7 +38,21 @@ router.add('GET', 'x-headers', (request) => { return new Response(JSON.stringify(headers)); }); -// router.add('GET', 'x-create-roleypoly-data', CreateRoleypolyData); + +// Root Zen <3 +router.addFallback('root', () => { + return respond({ + __warning: '🦊', + this: 'is', + a: 'fox-based', + web: 'application', + please: 'be', + mindful: 'of', + your: 'surroundings', + warning__: '🦊', + meta: uiPublicURI, + }); +}); addEventListener('fetch', (event: FetchEvent) => { event.respondWith(router.handle(event.request)); diff --git a/src/backend-worker/utils/api-tools.ts b/src/backend-worker/utils/api-tools.ts index 977c0b9..c56e6f1 100644 --- a/src/backend-worker/utils/api-tools.ts +++ b/src/backend-worker/utils/api-tools.ts @@ -4,7 +4,7 @@ import { permissions as Permissions, } from '../../common/utils/hasPermission'; import { Handler } from '../router'; -import { uiPublicURI } from './config'; +import { rootUsers, uiPublicURI } from './config'; import { Sessions, WrappedKVNamespace } from './kv'; export const formData = (obj: Record): string => { @@ -147,3 +147,21 @@ export const withSession = ( return await wrappedHandler(session)(request); }; + +export const isRoot = (userID: string): boolean => rootUsers.includes(userID); + +export const onlyRootUsers = (handler: Handler): Handler => + withSession((session) => (request: Request) => { + if (isRoot(session.user.id)) { + return handler(request); + } + + return respond( + { + error: 'not_found', + }, + { + status: 404, + } + ); + });