update onboard route
This commit is contained in:
parent
1c87e93d2f
commit
8ca379b6db
@ -8,29 +8,37 @@ import { createDynaBridgeClient } from "../../../utils/ddb";
|
||||
import DiscordOauth2 from "discord-oauth2";
|
||||
import { DoorAliasSchema, getDoorAliasID } from "../../../schema/DoorAlias";
|
||||
import { Counter } from "prom-client";
|
||||
import { z } from "zod";
|
||||
import zu from "zod_utilz";
|
||||
import { setResponseJson } from "../../../utils/responseUtils";
|
||||
|
||||
export interface OnboardRequest extends ServerlessEventObject<{}, UserAgentHeader> {
|
||||
newConfig?: string;
|
||||
export const OnboardRequestSchema = z.object({
|
||||
newConfig: zu.stringToJSON().optional(),
|
||||
code: z.string().optional(),
|
||||
state: zu.stringToJSON().optional(),
|
||||
}).partial()
|
||||
.refine(data => data.newConfig || (data.code && data.state), 'newConfig or (code and state) must be specified');
|
||||
|
||||
// for oauth redirect
|
||||
code?: string;
|
||||
state?: string;
|
||||
}
|
||||
export type OnboardRequest = z.infer<typeof OnboardRequestSchema>;
|
||||
|
||||
export interface DiscordOnboardingState {
|
||||
name: string;
|
||||
id: string;
|
||||
apiRedirect: string;
|
||||
}
|
||||
export interface OnboardRequestTwilio extends ServerlessEventObject<OnboardRequest, UserAgentHeader> { };
|
||||
|
||||
export const DiscordOnboardingStateSchema = z.object({
|
||||
name: z.string(),
|
||||
id: z.string(),
|
||||
apiRedirect: z.string(),
|
||||
});
|
||||
|
||||
export type DiscordOnboardingState = z.infer<typeof DiscordOnboardingStateSchema>;
|
||||
|
||||
const ONBOARDING_SCOPE = ['identify', 'email', 'guilds.join'];
|
||||
|
||||
export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest> = withMetrics('onboard', async (context, event, callback, metricsRegistry) => {
|
||||
export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequestTwilio> = withMetrics('onboard', async (context, event, callback, metricsRegistry) => {
|
||||
const response = new Twilio.Response();
|
||||
response.appendHeader('Content-Type', 'application/json');
|
||||
|
||||
registerMetrics(metricsRegistry);
|
||||
|
||||
const req = OnboardRequestSchema.parse(event);
|
||||
|
||||
const db = createDynaBridgeClient(context);
|
||||
|
||||
// return oauth link
|
||||
@ -41,23 +49,13 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
});
|
||||
|
||||
// create door config route
|
||||
if (event.code && event.state) {
|
||||
const code = event.code;
|
||||
let discordState: DiscordOnboardingState;
|
||||
|
||||
try {
|
||||
discordState = JSON.parse(event.state);
|
||||
} catch (e) {
|
||||
response.setStatusCode(400);
|
||||
response.setBody({ err: "invalid state" });
|
||||
return callback(null, response);
|
||||
}
|
||||
if (req.code && req.state) {
|
||||
const code = req.code;
|
||||
let discordState: DiscordOnboardingState = DiscordOnboardingStateSchema.parse(req.state);
|
||||
|
||||
const config = await db.entities.onboardDoorConfig.findById(getOnboardDoorId(discordState.name));
|
||||
if (!config || config.nonce !== discordState.id) {
|
||||
response.setStatusCode(404)
|
||||
.setBody({ err: "approval not found" });
|
||||
|
||||
setResponseJson(response, 404, { err: "approval not found" });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
@ -73,8 +71,7 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
});
|
||||
} catch (err) {
|
||||
console.log("something went wrong with discord authorization");
|
||||
response.setStatusCode(401);
|
||||
response.setBody({ err });
|
||||
setResponseJson(response, 401, { err });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
@ -84,9 +81,7 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
console.log(profileId);
|
||||
|
||||
if (!profileId) {
|
||||
response.setStatusCode(404);
|
||||
response.setBody({ err: "profile not found" });
|
||||
|
||||
setResponseJson(response, 404, { err: "profile not found" });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
@ -144,37 +139,26 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
// and all must succeed or none succeed
|
||||
try {
|
||||
await db.transaction([createDoorAlias, createDoorConfig, deleteOnboardingConfig]);
|
||||
response.setStatusCode(200);
|
||||
response.setBody({ redirect: context.DOORMAN_URL + `?door=${config.name}` });
|
||||
setResponseJson(response, 200, { redirect: context.DOORMAN_URL + `?door=${config.name}` });
|
||||
} catch (e) {
|
||||
getMetricFromRegistry<Counter>(metricsRegistry, OnboardMetrics.TRANSACTION_CONFLICT).inc(1);
|
||||
console.error(e);
|
||||
|
||||
response.setStatusCode(409);
|
||||
response.setBody({ err: "something went wrong during onboarding" });
|
||||
setResponseJson(response, 409, { err: "something went wrong during onboarding" });
|
||||
}
|
||||
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
let newConfig = event.newConfig;
|
||||
let newConfig = req.newConfig;
|
||||
|
||||
if (!newConfig) {
|
||||
response.setStatusCode(400);
|
||||
setResponseJson(response, 400, { err: "missing newConfig" });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
let newConfigParsed: OnboardDoorReq;
|
||||
|
||||
console.log("parsing config");
|
||||
try {
|
||||
newConfigParsed = OnboardDoorReqSchema.parse(JSON.parse(newConfig));
|
||||
} catch (err) {
|
||||
response.setStatusCode(400);
|
||||
response.setBody({ err });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
let newConfigParsed: OnboardDoorReq = OnboardDoorReqSchema.parse(newConfig);
|
||||
const newConfigObj = createOnboardDoorConfig(newConfigParsed);
|
||||
|
||||
// check if this name or buzzer is already registered?
|
||||
@ -182,8 +166,7 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
|
||||
if (existingAlias) {
|
||||
getMetricFromRegistry<Counter>(metricsRegistry, OnboardMetrics.BUZZER_CONFLICT).inc({ buzzer: newConfigObj.buzzer }, 1);
|
||||
response.setStatusCode(409);
|
||||
response.setBody({ err: `A buzzer is already registered with the number ${newConfigObj.buzzer}` });
|
||||
setResponseJson(response, 409, { err: `A buzzer is already registered with the number ${newConfigObj.buzzer}` });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
@ -191,8 +174,7 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
|
||||
if (existingConfig) {
|
||||
getMetricFromRegistry<Counter>(metricsRegistry, OnboardMetrics.NAME_CONFLICT).inc({ name: newConfigObj.name }, 1);
|
||||
response.setStatusCode(409);
|
||||
response.setBody({ err: `A buzzer is already registered with the name ${newConfigObj.name}` });
|
||||
setResponseJson(response, 409, { err: `A buzzer is already registered with the name ${newConfigObj.name}` });
|
||||
return callback(null, response);
|
||||
}
|
||||
|
||||
@ -202,11 +184,11 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
// save to DB, this is a middle step until discord auth comes in
|
||||
await db.entities.onboardDoorConfig.save(newConfigObj);
|
||||
|
||||
const discordState: DiscordOnboardingState = {
|
||||
const discordState: DiscordOnboardingState = DiscordOnboardingStateSchema.parse({
|
||||
name: newConfigObj.name,
|
||||
id: newConfigObj.nonce,
|
||||
apiRedirect: '/api/door/onboard',
|
||||
}
|
||||
});
|
||||
|
||||
const redirect = oauth.generateAuthUrl({
|
||||
scope: ONBOARDING_SCOPE,
|
||||
@ -214,7 +196,6 @@ export const handler: ServerlessFunctionSignature<TwilioContext, OnboardRequest>
|
||||
state: JSON.stringify(discordState),
|
||||
});
|
||||
|
||||
response.setStatusCode(200);
|
||||
response.setBody({ redirect });
|
||||
setResponseJson(response, 200, { redirect });
|
||||
return callback(null, response);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user