Skip to content

Commit

Permalink
add server-side check of access token update
Browse files Browse the repository at this point in the history
  • Loading branch information
lyc8503 committed Jan 26, 2024
1 parent 50f32b8 commit 1709e1a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 20 deletions.
16 changes: 12 additions & 4 deletions src/pages/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import axios from 'redaxios'

import apiConfig from '../../../config/api.config'
import siteConfig from '../../../config/site.config'
import { revealObfuscatedToken } from '../../utils/oAuthHandler'
import { getAuthPersonInfo, revealObfuscatedToken } from '../../utils/oAuthHandler'
import { compareHashedToken } from '../../utils/protectedRouteHandler'
import { getOdAuthTokens, storeOdAuthTokens } from '../../utils/odAuthTokenStore'
import { NextRequest, NextResponse } from 'next/server'
Expand Down Expand Up @@ -160,14 +160,22 @@ export async function checkAuthRoute(
export default async function handler(req: NextRequest): Promise<Response> {
// If method is POST, then the API is called by the client to store acquired tokens
if (req.method === 'POST') {
const { obfuscatedAccessToken, accessTokenExpiry, obfuscatedRefreshToken } = await req.json()
const accessToken = revealObfuscatedToken(obfuscatedAccessToken)
const refreshToken = revealObfuscatedToken(obfuscatedRefreshToken)
const { accessToken, accessTokenExpiry, refreshToken } = await req.json()

if (typeof accessToken !== 'string' || typeof refreshToken !== 'string') {
return new Response('Invalid request body', { status: 400 })
}

// verify identity of the authenticated user with the Microsoft Graph API
const { data, status } = await getAuthPersonInfo(accessToken)
if (status !== 200) {
return new Response("Non-200 response from Microsoft Graph API", { status: 500 })
}

if (data.userPrincipalName !== siteConfig.userPrincipalName) {
return new Response("Do not pretend to be the owner!", { status: 403 })
}

await storeOdAuthTokens({ accessToken, accessTokenExpiry, refreshToken })
return new Response('OK')
}
Expand Down
16 changes: 7 additions & 9 deletions src/pages/onedrive-oauth/step-3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,17 @@ export default function OAuthStep3({ accessToken, expiryTime, refreshToken, erro
</p>
<p className="py-1">
{'Final step, click the button below to store these tokens persistently before they expire ' +
`after ${Math.floor(expiryTimeLeft / 60)} minutes ${
expiryTimeLeft - Math.floor(expiryTimeLeft / 60) * 60
`after ${Math.floor(expiryTimeLeft / 60)} minutes ${expiryTimeLeft - Math.floor(expiryTimeLeft / 60) * 60
} seconds. ` +
"Don't worry, after storing them, onedrive-cf-index-ng will take care of token refreshes and updates after your site goes live."}
</p>

<div className="mb-2 mt-6 text-right">
<button
className={`rounded-lg bg-gradient-to-br px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 ${
buttonError
? 'from-red-500 to-orange-400 focus:ring-red-200 dark:focus:ring-red-800'
: 'from-green-500 to-teal-300 focus:ring-green-200 dark:focus:ring-green-800'
}`}
className={`rounded-lg bg-gradient-to-br px-4 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:ring-4 ${buttonError
? 'from-red-500 to-orange-400 focus:ring-red-200 dark:focus:ring-red-800'
: 'from-green-500 to-teal-300 focus:ring-green-200 dark:focus:ring-green-800'
}`}
onClick={sendAuthTokensToServer}
>
{buttonContent}
Expand Down Expand Up @@ -227,11 +225,11 @@ export async function getServerSideProps({ query }) {
return {
props: {
error: "Do not pretend to be the owner!",
description: "Authenticated user: " + data.userPrincipalName + "\n" + "siteConfig.userPrincipalName: " + siteConfig.userPrincipalName + "\n" + "Please check your config!"
description: "Authenticated user: " + data.userPrincipalName + "\n" + "UserPrincipalName in your config should match the authenticated user here!"
},
}
}

return {
props: {
error: null,
Expand Down
10 changes: 3 additions & 7 deletions src/utils/oAuthHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import apiConfig from '../../config/api.config'
// access tokens, and refresh tokens), used along with the following two functions
// Leave this for compatibility with the old version
const AES_SECRET_KEY = 'onedrive-vercel-index'
export function obfuscateToken(token: string): string {
// Encrypt token with AES
const encrypted = CryptoJS.AES.encrypt(token, AES_SECRET_KEY)
return encrypted.toString()
}

export function revealObfuscatedToken(obfuscated: string): string {
// Decrypt SHA256 obfuscated token
const decrypted = CryptoJS.AES.decrypt(obfuscated, AES_SECRET_KEY)
Expand Down Expand Up @@ -99,9 +95,9 @@ export async function sendTokenToServer(accessToken: string, refreshToken: strin
return await axios.post(
'/api',
{
obfuscatedAccessToken: obfuscateToken(accessToken),
accessToken: accessToken,
accessTokenExpiry: parseInt(expiryTime),
obfuscatedRefreshToken: obfuscateToken(refreshToken),
refreshToken: refreshToken,
},
{
headers: {
Expand Down

0 comments on commit 1709e1a

Please sign in to comment.