Better data key for window

This commit is contained in:
Gregory Schier
2025-02-24 22:34:10 -08:00
parent 52937c3097
commit c0dbe46318
5 changed files with 37 additions and 9 deletions

8
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"plugins/*" "plugins/*"
], ],
"dependencies": { "dependencies": {
"@yaakapp/api": "^0.4.1" "@yaakapp/api": "^0.5.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.7.4", "@types/node": "^22.7.4",
@@ -930,9 +930,9 @@
} }
}, },
"node_modules/@yaakapp/api": { "node_modules/@yaakapp/api": {
"version": "0.4.1", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.4.1.tgz", "resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.5.0.tgz",
"integrity": "sha512-qRpCuL2Wq9BJXbB6tHSQjaXGq0ZBQwnd87nWdeOPWMvmKCfFTPhxQh4x9/aFN1bTncNHcV3OdeXFTKMl0tB0Ng==", "integrity": "sha512-M0PPLGWQft+eQOOJ7ubwvRm3LTYXjAWQ8nniiqV3TkRcwa5++PteIH0OHV2L3Pei8cRQA8S25AD+RajyvFC8XQ==",
"dependencies": { "dependencies": {
"@types/node": "^22.5.4" "@types/node": "^22.5.4"
} }

View File

@@ -19,6 +19,6 @@
"workspaces-run": "^1.0.2" "workspaces-run": "^1.0.2"
}, },
"dependencies": { "dependencies": {
"@yaakapp/api": "^0.4.1" "@yaakapp/api": "^0.5.0"
} }
} }

View File

@@ -2,7 +2,7 @@ import { Context } from '@yaakapp/api';
import { createHash, randomBytes } from 'node:crypto'; import { createHash, randomBytes } from 'node:crypto';
import { getAccessToken } from '../getAccessToken'; import { getAccessToken } from '../getAccessToken';
import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken'; import { getOrRefreshAccessToken } from '../getOrRefreshAccessToken';
import { AccessToken, storeToken } from '../store'; import { AccessToken, getDataDirKey, storeToken } from '../store';
export const PKCE_SHA256 = 'S256'; export const PKCE_SHA256 = 'S256';
export const PKCE_PLAIN = 'plain'; export const PKCE_PLAIN = 'plain';
@@ -63,9 +63,18 @@ export async function getAuthorizationCode(
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const authorizationUrlStr = authorizationUrl.toString(); const authorizationUrlStr = authorizationUrl.toString();
console.log('Authorizing', authorizationUrlStr); console.log('Authorizing', authorizationUrlStr);
let foundCode = false;
let { close } = await ctx.window.openUrl({ let { close } = await ctx.window.openUrl({
url: authorizationUrlStr, url: authorizationUrlStr,
label: 'oauth-authorization-url', label: 'oauth-authorization-url',
dataDirKey: await getDataDirKey(ctx, contextId),
async onClose() {
if (!foundCode) {
reject(new Error('Authorization window closed'));
}
},
async onNavigate({ url: urlStr }) { async onNavigate({ url: urlStr }) {
const url = new URL(urlStr); const url = new URL(urlStr);
if (url.searchParams.has('error')) { if (url.searchParams.has('error')) {
@@ -77,6 +86,7 @@ export async function getAuthorizationCode(
} }
// Close the window here, because we don't need it anymore! // Close the window here, because we don't need it anymore!
foundCode = true;
close(); close();
const response = await getAccessToken(ctx, { const response = await getAccessToken(ctx, {

View File

@@ -9,7 +9,7 @@ import { DEFAULT_PKCE_METHOD, getAuthorizationCode, PKCE_PLAIN, PKCE_SHA256 } fr
import { getClientCredentials } from './grants/clientCredentials'; import { getClientCredentials } from './grants/clientCredentials';
import { getImplicit } from './grants/implicit'; import { getImplicit } from './grants/implicit';
import { getPassword } from './grants/password'; 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'; type GrantType = 'authorization_code' | 'implicit' | 'password' | 'client_credentials';
@@ -71,7 +71,6 @@ export const plugin: PluginDefinition = {
actions: [ actions: [
{ {
label: 'Copy Current Token', label: 'Copy Current Token',
icon: 'copy',
async onSelect(ctx, { contextId }) { async onSelect(ctx, { contextId }) {
const token = await getToken(ctx, contextId); const token = await getToken(ctx, contextId);
if (token == null) { if (token == null) {
@@ -84,7 +83,6 @@ export const plugin: PluginDefinition = {
}, },
{ {
label: 'Delete Token', label: 'Delete Token',
icon: 'trash',
async onSelect(ctx, { contextId }) { async onSelect(ctx, { contextId }) {
if (await deleteToken(ctx, contextId)) { if (await deleteToken(ctx, contextId)) {
await ctx.toast.show({ message: 'Token deleted', color: 'success' }); 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: [ args: [
{ {

View File

@@ -22,10 +22,24 @@ export async function deleteToken(ctx: Context, contextId: string) {
return ctx.store.delete(tokenStoreKey(contextId)); return ctx.store.delete(tokenStoreKey(contextId));
} }
export async function resetDataDirKey(ctx: Context, contextId: string) {
const key = new Date().toISOString();
return ctx.store.set<string>(dataDirStoreKey(contextId), key);
}
export async function getDataDirKey(ctx: Context, contextId: string) {
const key = (await ctx.store.get<string>(dataDirStoreKey(contextId))) ?? 'default';
return `${contextId}::${key}`;
}
function tokenStoreKey(context_id: string) { function tokenStoreKey(context_id: string) {
return ['token', context_id].join('::'); return ['token', context_id].join('::');
} }
function dataDirStoreKey(context_id: string) {
return ['data_dir', context_id].join('::');
}
export interface AccessToken { export interface AccessToken {
response: AccessTokenRawResponse, response: AccessTokenRawResponse,
expiresAt: number | null; expiresAt: number | null;