chore: temporarily loosen CORS, add OAuth state info for backend bouncing

This commit is contained in:
41666 2021-03-13 15:49:36 -05:00
parent ed82a67594
commit 6edfe7455f
8 changed files with 72 additions and 9 deletions

View file

@ -1,4 +1,5 @@
import KSUID from 'ksuid';
import { StateSession } from '@roleypoly/types';
import { getQuery, isAllowedCallbackHost, setupStateSession } from '../utils/api-tools';
import { Bounce } from '../utils/bounce';
import { apiPublicURI, botClientID } from '../utils/config';
@ -16,9 +17,17 @@ const buildURL = (params: URLParams) =>
)}&state=${params.state}`;
export const LoginBounce = async (request: Request): Promise<Response> => {
const state = await KSUID.random();
const stateSessionData: StateSession = {};
const { cbh: callbackHost } = getQuery(request);
if (callbackHost && isAllowedCallbackHost(callbackHost)) {
stateSessionData.callbackHost = callbackHost;
}
const state = await setupStateSession(stateSessionData);
const redirectURI = `${apiPublicURI}/login-callback`;
const clientID = botClientID;
return Bounce(buildURL({ state: state.string, redirectURI, clientID }));
return Bounce(buildURL({ state, redirectURI, clientID }));
};

View file

@ -1,9 +1,17 @@
import { AuthTokenResponse, DiscordUser, GuildSlug, SessionData } from '@roleypoly/types';
import {
AuthTokenResponse,
DiscordUser,
GuildSlug,
SessionData,
StateSession,
} from '@roleypoly/types';
import KSUID from 'ksuid';
import {
AuthType,
discordFetch,
formData,
getStateSession,
isAllowedCallbackHost,
parsePermissions,
resolveFailures,
userAgent,
@ -21,8 +29,9 @@ const AuthErrorResponse = (extra?: string) =>
export const LoginCallback = resolveFailures(
AuthErrorResponse,
async (request: Request): Promise<Response> => {
const query = new URL(request.url).searchParams;
let bounceBaseUrl = uiPublicURI;
const query = new URL(request.url).searchParams;
const stateValue = query.get('state');
if (stateValue === null) {
@ -37,6 +46,14 @@ export const LoginCallback = resolveFailures(
if (currentTime > stateExpiry) {
return AuthErrorResponse('state expired');
}
const stateSession = await getStateSession<StateSession>(state.string);
if (
stateSession?.callbackHost &&
isAllowedCallbackHost(stateSession.callbackHost)
) {
bounceBaseUrl = stateSession.callbackHost;
}
} catch (e) {
return AuthErrorResponse('state invalid');
}
@ -90,7 +107,7 @@ export const LoginCallback = resolveFailures(
await Sessions.put(sessionID.string, sessionData, 60 * 60 * 6);
return Bounce(
uiPublicURI + '/machinery/new-session?session_id=' + sessionID.string
bounceBaseUrl + '/machinery/new-session?session_id=' + sessionID.string
);
}
);