feat(api): add revoke-session

This commit is contained in:
41666 2020-12-17 16:14:27 -05:00
parent b7921a830a
commit 89fbb01142
4 changed files with 34 additions and 21 deletions

View file

@ -18,7 +18,7 @@ const fail = () =>
);
export const GetPickerData = withSession(
(session?: SessionData) => async (request: Request): Promise<Response> => {
(session: SessionData) => async (request: Request): Promise<Response> => {
const url = new URL(request.url);
const [, , guildID] = url.pathname.split('/');
@ -33,8 +33,8 @@ export const GetPickerData = withSession(
);
}
const { id: userID } = session?.user as DiscordUser;
const guilds = session?.guilds as GuildSlug[];
const { id: userID } = session.user as DiscordUser;
const guilds = session.guilds as GuildSlug[];
// Save a Discord API request by checking if this user is a member by session first
const checkGuild = guilds.find((guild) => guild.id === guildID);
@ -72,8 +72,5 @@ export const GetPickerData = withSession(
};
return respond(presentableGuild);
},
{
mustAuthenticate: true,
}
);

View file

@ -0,0 +1,26 @@
import { SessionData } from 'roleypoly/common/types';
import { formData, respond, withSession } from '../utils/api-tools';
import { botClientID, botClientSecret } from '../utils/config';
import { Sessions } from '../utils/kv';
export const RevokeSession = withSession(
(session: SessionData) => async (request: Request) => {
const tokenRequest = {
token: session.tokens.access_token,
client_id: botClientID,
client_secret: botClientSecret,
};
await fetch('https://discord.com/api/v8/oauth2/token/revoke', {
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
body: formData(tokenRequest),
});
await Sessions.delete(session.sessionID);
return respond({ ok: true });
}
);

View file

@ -4,6 +4,7 @@ import { GetSession } from './handlers/get-session';
import { GetSlug } from './handlers/get-slug';
import { LoginBounce } from './handlers/login-bounce';
import { LoginCallback } from './handlers/login-callback';
import { RevokeSession } from './handlers/revoke-session';
import { Router } from './router';
const router = new Router();
@ -15,6 +16,7 @@ router.addFallback('root', () => {
router.add('GET', 'bot-join', BotJoin);
router.add('GET', 'login-bounce', LoginBounce);
router.add('GET', 'login-callback', LoginCallback);
router.add('GET', 'revoke-session', RevokeSession);
router.add('GET', 'get-session', GetSession);
router.add('GET', 'get-slug', GetSlug);
router.add('GET', 'get-picker-data', GetPickerData);

View file

@ -121,29 +121,17 @@ type WithSessionOpts = {
};
export const withSession = (
wrappedHandler: (session?: SessionData) => Handler,
{ mustAuthenticate }: WithSessionOpts = {}
wrappedHandler: (session: SessionData) => Handler
): Handler => async (request: Request): Promise<Response> => {
const sessionID = getSessionID(request);
if (!sessionID) {
if (mustAuthenticate) {
return NotAuthenticated('missing authentication');
} else {
return await wrappedHandler(undefined)(request);
}
return NotAuthenticated('missing authentication');
}
const session = await Sessions.get<SessionData>(sessionID.id);
if (!session) {
if (mustAuthenticate) {
return NotAuthenticated('authentication expired or not found');
} else {
return await wrappedHandler(undefined)(request);
}
return NotAuthenticated('authentication expired or not found');
}
return await wrappedHandler(session)(request);
};
export const mustBeAuthenticated = (handler: Handler) =>
withSession(() => handler, { mustAuthenticate: true });