From 2e6c652ea1f0923dcb43d715f90db9d31eaa868d Mon Sep 17 00:00:00 2001 From: spencerwooo Date: Fri, 31 Dec 2021 16:56:18 +0800 Subject: [PATCH] lets try storing as tmp file again --- pages/api/index.ts | 22 ++++-- pages/onedrive-vercel-index-oauth/step-3.tsx | 76 +++++++++++++------- utils/odAuthTokenStore.ts | 54 +++++--------- 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/pages/api/index.ts b/pages/api/index.ts index 5242392..9ba9882 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -1,17 +1,26 @@ +import os from 'os' import { posix as pathPosix } from 'path' import type { NextApiRequest, NextApiResponse } from 'next' import axios from 'axios' +import Keyv from 'keyv' +import { KeyvFile } from 'keyv-file' import apiConfig from '../../config/api.json' import siteConfig from '../../config/site.json' import { revealObfuscatedToken } from '../../utils/oAuthHandler' import { compareHashedToken } from '../../utils/protectedRouteHandler' -import TokenStore from '../../utils/odAuthTokenStore' +import { getOdAuthTokens, storeOdAuthTokens } from '../../utils/odAuthTokenStore' const basePath = pathPosix.resolve('/', siteConfig.baseDirectory) const clientSecret = revealObfuscatedToken(apiConfig.obfuscatedClientSecret) -const tokenStore = new TokenStore() + +const keyv = new Keyv({ + store: new KeyvFile({ + filename: `${os.tmpdir()}/od-auth-token.json`, + }), +}) +console.log(`kv init - ${os.tmpdir()}/od-auth-token.json`) const encodePath = (path: string) => { let encodedPath = pathPosix.join(basePath, pathPosix.resolve('/', path)) @@ -23,8 +32,7 @@ const encodePath = (path: string) => { } async function getAccessToken(): Promise { - const { accessToken, refreshToken } = await tokenStore.getOdAuthTokens() - console.log(accessToken, refreshToken) + const { accessToken, refreshToken } = await getOdAuthTokens(keyv) // Return in storage access token if it is still valid if (typeof accessToken === 'string') { @@ -54,10 +62,11 @@ async function getAccessToken(): Promise { if ('access_token' in resp.data && 'refresh_token' in resp.data) { const { expires_in, access_token, refresh_token } = resp.data - await tokenStore.storeOdAuthTokens({ + await storeOdAuthTokens({ accessToken: access_token, accessTokenExpiry: parseInt(expires_in), refreshToken: refresh_token, + keyv, }) console.log('Fetch new access token with stored refresh token.') return access_token @@ -78,10 +87,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return } - await tokenStore.storeOdAuthTokens({ + await storeOdAuthTokens({ accessToken, accessTokenExpiry, refreshToken, + keyv, }) res.status(200).send('OK') return diff --git a/pages/onedrive-vercel-index-oauth/step-3.tsx b/pages/onedrive-vercel-index-oauth/step-3.tsx index ed04b4b..f81be4a 100644 --- a/pages/onedrive-vercel-index-oauth/step-3.tsx +++ b/pages/onedrive-vercel-index-oauth/step-3.tsx @@ -1,5 +1,7 @@ +import axios from 'axios' import Head from 'next/head' import router from 'next/router' +import { useState } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import siteConfig from '../../config/site.json' @@ -7,9 +9,49 @@ import Navbar from '../../components/Navbar' import Footer from '../../components/Footer' import { obfuscateToken, requestTokenWithAuthCode } from '../../utils/oAuthHandler' -import axios from 'axios' +import { LoadingIcon } from '../../components/Loading' + +export default function OAuthStep3({ accessToken, expiryTime, refreshToken, error, description, errorUri }) { + const [buttonContent, setButtonContent] = useState( + <> + Store tokens + + ) + + const sendAuthTokensToServer = async () => { + setButtonContent( + <> + Store tokens + + ) + + await axios + .post( + '/api', + { + obfuscatedAccessToken: obfuscateToken(accessToken), + accessTokenExpiry: parseInt(expiryTime), + obfuscatedRefreshToken: obfuscateToken(refreshToken), + }, + { + headers: { + 'Content-Type': 'application/json', + }, + } + ) + .then(_ => { + console.log('Tokens sent to server') + setButtonContent( + <> + Stored! Going home... + + ) + setTimeout(() => { + router.push('/') + }, 2000) + }) + } -export default function OAuthStep3({ accessToken, refreshToken, error, description, errorUri }) { return (
@@ -89,16 +131,16 @@ export default function OAuthStep3({ accessToken, refreshToken, error, descripti )} -

Your onedrive-vercel-index should be up and running. Go back home to find out.

+

+ Click the button below to save these tokens securely on Vercel before they expire. +

@@ -140,24 +182,6 @@ export async function getServerSideProps({ query }) { const { expiryTime, accessToken, refreshToken } = response - // await tokenStore.storeOdAuthTokens({ accessToken, accessTokenExpiry: parseInt(expiryTime), refreshToken }) - - // We perform a POST request to the default API route to store the tokens inside the main route memory - // This is a bit of a hack, but it's the only way to get the tokens to the main route - await axios.post( - '/api', - { - obfuscatedAccessToken: obfuscateToken(accessToken), - accessTokenExpiry: parseInt(expiryTime), - obfuscatedRefreshToken: obfuscateToken(refreshToken), - }, - { - headers: { - 'Content-Type': 'application/json', - }, - } - ) - return { props: { error: null, diff --git a/utils/odAuthTokenStore.ts b/utils/odAuthTokenStore.ts index 6b53912..23c71f8 100644 --- a/utils/odAuthTokenStore.ts +++ b/utils/odAuthTokenStore.ts @@ -1,45 +1,29 @@ // This should be only used on the server side, where the tokens are stored with KV store using // a file system based storage. The tokens are stored in the file system as JSON at /tmp path. -import os from 'os' import Keyv from 'keyv' -import { KeyvFile } from 'keyv-file' -// console.log(`${os.tmpdir()}/od-auth-token.json`) +export async function getOdAuthTokens(keyv: Keyv): Promise<{ accessToken: unknown; refreshToken: unknown }> { + const accessToken = await keyv.get('access_token') + const refreshToken = await keyv.get('refresh_token') -export default class TokenStore { - kv: Keyv - - constructor() { - this.kv = new Keyv() - // this.kv = new Keyv({ - // store: new KeyvFile({ - // filename: `${os.tmpdir()}/od-auth-token.json`, - // }), - // }) - console.log('TokenStore constructor') - } - - async getOdAuthTokens(): Promise<{ accessToken: unknown; refreshToken: unknown }> { - const accessToken = await this.kv.get('access_token') - const refreshToken = await this.kv.get('refresh_token') - - return { - accessToken, - refreshToken, - } - } - - async storeOdAuthTokens({ + return { accessToken, - accessTokenExpiry, refreshToken, - }: { - accessToken: string - accessTokenExpiry: number - refreshToken: string - }): Promise { - await this.kv.set('access_token', accessToken, accessTokenExpiry) - await this.kv.set('refresh_token', refreshToken) } } + +export async function storeOdAuthTokens({ + accessToken, + accessTokenExpiry, + refreshToken, + keyv, +}: { + accessToken: string + accessTokenExpiry: number + refreshToken: string + keyv: Keyv +}): Promise { + await keyv.set('access_token', accessToken, accessTokenExpiry) + await keyv.set('refresh_token', refreshToken) +}