feat: add tm show (#1199)

This commit is contained in:
Ralph Khreish
2025-09-12 03:34:32 +02:00
committed by GitHub
parent 3eeb19590a
commit 77e1ddc237
27 changed files with 2274 additions and 1740 deletions

View File

@@ -31,7 +31,7 @@ export class AuthManager {
private organizationService?: OrganizationService;
private constructor(config?: Partial<AuthConfig>) {
this.credentialStore = new CredentialStore(config);
this.credentialStore = CredentialStore.getInstance(config);
this.supabaseClient = new SupabaseAuthClient();
this.oauthService = new OAuthService(this.credentialStore, config);
@@ -73,6 +73,7 @@ export class AuthManager {
*/
static resetInstance(): void {
AuthManager.instance = null;
CredentialStore.resetInstance();
}
/**

View File

@@ -19,15 +19,39 @@ import { getLogger } from '../logger/index.js';
* human-readable persisted format in the auth.json file.
*/
export class CredentialStore {
private static instance: CredentialStore | null = null;
private logger = getLogger('CredentialStore');
private config: AuthConfig;
// Clock skew tolerance for expiry checks (30 seconds)
private readonly CLOCK_SKEW_MS = 30_000;
constructor(config?: Partial<AuthConfig>) {
private constructor(config?: Partial<AuthConfig>) {
this.config = getAuthConfig(config);
}
/**
* Get the singleton instance of CredentialStore
*/
static getInstance(config?: Partial<AuthConfig>): CredentialStore {
if (!CredentialStore.instance) {
CredentialStore.instance = new CredentialStore(config);
} else if (config) {
// Warn if config is provided after initialization
const logger = getLogger('CredentialStore');
logger.warn(
'getInstance called with config after initialization; config is ignored.'
);
}
return CredentialStore.instance;
}
/**
* Reset the singleton instance (useful for testing)
*/
static resetInstance(): void {
CredentialStore.instance = null;
}
/**
* Get stored authentication credentials
* @returns AuthCredentials with expiresAt as number (milliseconds) for runtime use

View File

@@ -5,7 +5,7 @@
export { AuthManager } from './auth-manager.js';
export { CredentialStore } from './credential-store.js';
export { OAuthService } from './oauth-service.js';
export { SupabaseSessionStorage } from './supabase-session-storage';
export { SupabaseSessionStorage } from './supabase-session-storage.js';
export type {
Organization,
Brief,

View File

@@ -7,9 +7,9 @@
*/
import { SupportedStorage } from '@supabase/supabase-js';
import { CredentialStore } from './credential-store';
import { AuthCredentials } from './types';
import { getLogger } from '../logger';
import { CredentialStore } from './credential-store.js';
import { AuthCredentials } from './types.js';
import { getLogger } from '../logger/index.js';
const STORAGE_KEY = 'sb-taskmaster-auth-token';

View File

@@ -10,8 +10,8 @@ import {
} from '@supabase/supabase-js';
import { AuthenticationError } from '../auth/types.js';
import { getLogger } from '../logger/index.js';
import { SupabaseSessionStorage } from '../auth/supabase-session-storage';
import { CredentialStore } from '../auth/credential-store';
import { SupabaseSessionStorage } from '../auth/supabase-session-storage.js';
import { CredentialStore } from '../auth/credential-store.js';
export class SupabaseAuthClient {
private client: SupabaseJSClient | null = null;
@@ -19,7 +19,7 @@ export class SupabaseAuthClient {
private logger = getLogger('SupabaseAuthClient');
constructor() {
const credentialStore = new CredentialStore();
const credentialStore = CredentialStore.getInstance();
this.sessionStorage = new SupabaseSessionStorage(credentialStore);
}