From c0dbe46318c53ef114c238f8ed1464fd4e807e99 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 24 Feb 2025 22:34:10 -0800 Subject: [PATCH] Better data key for window --- package-lock.json | 8 ++++---- package.json | 2 +- .../auth-oauth2/src/grants/authorizationCode.ts | 12 +++++++++++- plugins/auth-oauth2/src/index.ts | 10 +++++++--- plugins/auth-oauth2/src/store.ts | 14 ++++++++++++++ 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bf7fb64..b7532360 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "plugins/*" ], "dependencies": { - "@yaakapp/api": "^0.4.1" + "@yaakapp/api": "^0.5.0" }, "devDependencies": { "@types/node": "^22.7.4", @@ -930,9 +930,9 @@ } }, "node_modules/@yaakapp/api": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.4.1.tgz", - "integrity": "sha512-qRpCuL2Wq9BJXbB6tHSQjaXGq0ZBQwnd87nWdeOPWMvmKCfFTPhxQh4x9/aFN1bTncNHcV3OdeXFTKMl0tB0Ng==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.0.tgz", + "integrity": "sha512-M0PPLGWQft+eQOOJ7ubwvRm3LTYXjAWQ8nniiqV3TkRcwa5++PteIH0OHV2L3Pei8cRQA8S25AD+RajyvFC8XQ==", "dependencies": { "@types/node": "^22.5.4" } diff --git a/package.json b/package.json index 29d6f466..ef57489a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,6 @@ "workspaces-run": "^1.0.2" }, "dependencies": { - "@yaakapp/api": "^0.4.1" + "@yaakapp/api": "^0.5.0" } } diff --git a/plugins/auth-oauth2/src/grants/authorizationCode.ts b/plugins/auth-oauth2/src/grants/authorizationCode.ts index 8d06dd7a..247a3a72 100644 --- a/plugins/auth-oauth2/src/grants/authorizationCode.ts +++ b/plugins/auth-oauth2/src/grants/authorizationCode.ts @@ -2,7 +2,7 @@ import { Context } from '@yaakapp/api'; import { createHash, randomBytes } from 'node:crypto'; import { getAccessToken } from '../getAccessToken'; import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; -import { AccessToken, storeToken } from '../store'; +import { AccessToken, getDataDirKey, storeToken } from '../store'; export const PKCE_SHA256 = 'S256'; export const PKCE_PLAIN = 'plain'; @@ -63,9 +63,18 @@ export async function getAuthorizationCode( return new Promise(async (resolve, reject) => { const authorizationUrlStr = authorizationUrl.toString(); console.log('Authorizing', authorizationUrlStr); + + let foundCode = false; + let { close } = await ctx.window.openUrl({ url: authorizationUrlStr, label: 'oauth-authorization-url', + dataDirKey: await getDataDirKey(ctx, contextId), + async onClose() { + if (!foundCode) { + reject(new Error('Authorization window closed')); + } + }, async onNavigate({ url: urlStr }) { const url = new URL(urlStr); if (url.searchParams.has('error')) { @@ -77,6 +86,7 @@ export async function getAuthorizationCode( } // Close the window here, because we don't need it anymore! + foundCode = true; close(); const response = await getAccessToken(ctx, { diff --git a/plugins/auth-oauth2/src/index.ts b/plugins/auth-oauth2/src/index.ts index 43ade852..60ae2cf3 100644 --- a/plugins/auth-oauth2/src/index.ts +++ b/plugins/auth-oauth2/src/index.ts @@ -9,7 +9,7 @@ import { DEFAULT_PKCE_METHOD, getAuthorizationCode, PKCE_PLAIN, PKCE_SHA256 } fr import { getClientCredentials } from './grants/clientCredentials'; import { getImplicit } from './grants/implicit'; import { getPassword } from './grants/password'; -import { AccessToken, deleteToken, getToken } from './store'; +import { AccessToken, deleteToken, getToken, resetDataDirKey } from './store'; type GrantType = 'authorization_code' | 'implicit' | 'password' | 'client_credentials'; @@ -71,7 +71,6 @@ export const plugin: PluginDefinition = { actions: [ { label: 'Copy Current Token', - icon: 'copy', async onSelect(ctx, { contextId }) { const token = await getToken(ctx, contextId); if (token == null) { @@ -84,7 +83,6 @@ export const plugin: PluginDefinition = { }, { label: 'Delete Token', - icon: 'trash', async onSelect(ctx, { contextId }) { if (await deleteToken(ctx, contextId)) { await ctx.toast.show({ message: 'Token deleted', color: 'success' }); @@ -93,6 +91,12 @@ export const plugin: PluginDefinition = { } }, }, + { + label: 'Clear Window Session', + async onSelect(ctx, { contextId }) { + await resetDataDirKey(ctx, contextId); + }, + }, ], args: [ { diff --git a/plugins/auth-oauth2/src/store.ts b/plugins/auth-oauth2/src/store.ts index bc1675ed..89bf43e6 100644 --- a/plugins/auth-oauth2/src/store.ts +++ b/plugins/auth-oauth2/src/store.ts @@ -22,10 +22,24 @@ export async function deleteToken(ctx: Context, contextId: string) { return ctx.store.delete(tokenStoreKey(contextId)); } +export async function resetDataDirKey(ctx: Context, contextId: string) { + const key = new Date().toISOString(); + return ctx.store.set(dataDirStoreKey(contextId), key); +} + +export async function getDataDirKey(ctx: Context, contextId: string) { + const key = (await ctx.store.get(dataDirStoreKey(contextId))) ?? 'default'; + return `${contextId}::${key}`; +} + function tokenStoreKey(context_id: string) { return ['token', context_id].join('::'); } +function dataDirStoreKey(context_id: string) { + return ['data_dir', context_id].join('::'); +} + export interface AccessToken { response: AccessTokenRawResponse, expiresAt: number | null;