Skip to content

Commit

Permalink
use seesion token to extract api token
Browse files Browse the repository at this point in the history
  • Loading branch information
gregra81 committed Dec 9, 2023
1 parent 170253b commit db63f77
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 23 deletions.
28 changes: 17 additions & 11 deletions src/helpers/auth.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import jwt from 'jsonwebtoken';
import { Http401Error, Http500Error } from './errors';
import type { ParsedUrlQuery } from 'querystring';

export const mondayWorkflowAuthentication = (req: NextApiRequest, res: NextApiResponse) => {
const signingSecret = process.env.MONDAY_SIGNING_SECRET;
if (!signingSecret) {
throw new Http500Error('Unable to authenticate request');
}
const authorization = req.headers.authorization ?? req.query?.token as string;
const authorization = req.headers.authorization ?? (req.query?.token as string);
if (!authorization) {
throw new Http401Error('not authenticated, no credentials in request');
}
Expand All @@ -26,25 +27,30 @@ export const mondayWorkflowAuthentication = (req: NextApiRequest, res: NextApiRe
};
};

export const mondayViewAuthentication = (req: NextApiRequest, res: NextApiResponse) => {
export const mondayViewAuthentication = (query: ParsedUrlQuery) => {
const appSecret = process.env.MONDAY_APP_SECRET;
if (!appSecret) {
throw new Http500Error('Unable to authenticate request');
}
const authorization = req.headers.authorization ?? req.query?.token as string;
if (!authorization) {
throw new Http401Error('not authenticated, no credentials in request');
}

// @ts-ignore
const { exp, dat } = jwt.verify(authorization, appSecret);
const sessionToken = query['sessionToken'] as string;
if (!sessionToken) {
throw new Http401Error('not authenticated, no sessionToken in query');
}
const { exp, dat } = jwt.verify(sessionToken, appSecret) as {
exp: number;
dat: { account_id: string; user_id: string };
};
if (checkIfExpired(exp)) {
throw new Http401Error('authentication error, expired token');
}
const { account_id: accountId, user_id: userId } = dat || {};
if (!accountId || !userId) {
return res.status(401).json({ error: 'authentication error, could not verify credentials' });

if (!dat?.account_id || !dat?.user_id) {
throw new Http401Error('authentication error, could not verify credentials');
}

const userId = Number(dat.user_id);
const accountId = Number(dat.account_id);
return {
accountId,
userId,
Expand Down
10 changes: 4 additions & 6 deletions src/helpers/token-storage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { SecureStorage } from '@mondaycom/apps-sdk';
import { NextApiRequest } from 'next';

const storage = new SecureStorage();
export function getToken<T = { value: string | null }>(key: string): Promise<T | null> {
Expand All @@ -8,11 +7,10 @@ export function getToken<T = { value: string | null }>(key: string): Promise<T |
export const setToken = (key: string, value: string) => storage.set(key, value);
export const removeToken = (key: string) => storage.delete(key);

export const getMondayToken = async (cookies: Record<string, string | undefined>): Promise<string | null> => {
const tokenKey = cookies['monday_token'];
if (!tokenKey) {
return null;
}
export const getMondayTokenKey = (accountId: number, userId: number) => `monday_token_${accountId}_${userId}`;

export const getMondayToken = async (accountId: number, userId: number): Promise<string | null> => {
const tokenKey = getMondayTokenKey(accountId, userId);
const token = await getToken(tokenKey);

return token?.value ?? null;
Expand Down
12 changes: 7 additions & 5 deletions src/pages/api/oauth/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import axios from 'axios';
import { MONDAY_OAUTH_TOKEN_URL } from '../../../constants/monday';
import jwt from 'jsonwebtoken';
import { setToken } from '../../../helpers/token-storage';
import { getMondayTokenKey, setToken } from '../../../helpers/token-storage';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const authPayload = {
Expand All @@ -16,11 +16,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const data = response.data;

// store token in secret storage and redirect to app
const decodedData = jwt.decode(data.access_token);
const decodedData = jwt.decode(data.access_token) as { actid: string; uid: string };

// @ts-ignore
const tokenKey = `monday_token_${decodedData.actid}_${decodedData.uid}`;
if (!decodedData) {
res.status(400).json({ error: 'Invalid token' });
return;
}
const tokenKey = getMondayTokenKey(Number(decodedData.actid), Number(decodedData.uid));
await setToken(tokenKey, data.access_token);
res.setHeader('set-cookie', `monday_token=${tokenKey}; path=/; samesite=lax; httponly;`);
res.redirect('/');
}
4 changes: 3 additions & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as querystring from 'querystring';
import { MONDAY_OAUTH_AUTH_URL } from '../constants/monday';
import { getMondayToken } from '../helpers/token-storage';
import { storage } from '../helpers/storage/server';
import { mondayViewAuthentication } from '../helpers/auth';

export default function Home({ data }) {
const [isComponentVisible, setIsComponentVisible] = useState(false);
Expand All @@ -35,7 +36,8 @@ export default function Home({ data }) {
}

export const getServerSideProps = (async (context) => {
const mondayToken = await getMondayToken(context.req.cookies);
const { accountId, userId } = mondayViewAuthentication(context.query);
const mondayToken = await getMondayToken(accountId, userId);

if (!mondayToken) {
return mondayAuthorize();
Expand Down

1 comment on commit db63f77

@vercel
Copy link

@vercel vercel bot commented on db63f77 Dec 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

monday-gpt-app – ./

monday-gpt-app.vercel.app
monday-gpt-app-git-main-gregrash.vercel.app
monday-gpt-app-gregrash.vercel.app

Please sign in to comment.