Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions src/plus/integrations/authentication/integrationAuthentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export interface IntegrationAuthenticationProvider extends Disposable {
deleteSession(descriptor?: IntegrationAuthenticationSessionDescriptor): Promise<void>;
getSession(
descriptor?: IntegrationAuthenticationSessionDescriptor,
options?: { createIfNeeded?: boolean; forceNewSession?: boolean; source?: Sources },
options?:
| { createIfNeeded?: boolean; forceNewSession?: boolean; sync?: never; source?: Sources }
| { createIfNeeded?: never; forceNewSession?: never; sync: boolean; source?: Sources },
): Promise<ProviderAuthenticationSession | undefined>;
get onDidChange(): Event<void>;
}
Expand All @@ -73,7 +75,21 @@ abstract class IntegrationAuthenticationProviderBase<ID extends IntegrationId =
protected abstract fetchOrCreateSession(
storedSession: ProviderAuthenticationSession | undefined,
descriptor?: IntegrationAuthenticationSessionDescriptor,
options?: { createIfNeeded?: boolean; forceNewSession?: boolean; refreshIfExpired?: boolean; source?: Sources },
options?:
| {
createIfNeeded?: boolean;
forceNewSession?: boolean;
sync?: never;
refreshIfExpired?: boolean;
source?: Sources;
}
| {
createIfNeeded?: never;
forceNewSession?: never;
sync: boolean;
refreshIfExpired?: boolean;
source?: Sources;
},
): Promise<ProviderAuthenticationSession | undefined>;

protected abstract deleteAllSecrets(sessionId: string): Promise<void>;
Expand Down Expand Up @@ -129,7 +145,9 @@ abstract class IntegrationAuthenticationProviderBase<ID extends IntegrationId =
@debug()
async getSession(
descriptor?: IntegrationAuthenticationSessionDescriptor,
options?: { createIfNeeded?: boolean; forceNewSession?: boolean; source?: Sources },
options?:
| { createIfNeeded?: boolean; forceNewSession?: boolean; sync?: never; source?: Sources }
| { createIfNeeded?: never; forceNewSession?: never; sync: boolean; source?: Sources },
): Promise<ProviderAuthenticationSession | undefined> {
const sessionId = this.getSessionId(descriptor);

Expand Down Expand Up @@ -254,13 +272,27 @@ export abstract class CloudIntegrationAuthenticationProvider<
protected override async fetchOrCreateSession(
storedSession: ProviderAuthenticationSession | undefined,
descriptor?: IntegrationAuthenticationSessionDescriptor,
options?: { createIfNeeded?: boolean; forceNewSession?: boolean; refreshIfExpired?: boolean; source?: Sources },
options?:
| {
createIfNeeded?: boolean;
forceNewSession?: boolean;
sync?: never;
refreshIfExpired?: boolean;
source?: Sources;
}
| {
createIfNeeded?: never;
forceNewSession?: never;
sync: boolean;
refreshIfExpired?: boolean;
source?: Sources;
},
): Promise<ProviderAuthenticationSession | undefined> {
// TODO: This is a stopgap to make sure we're not hammering the api on automatic calls to get the session.
// Ultimately we want to timestamp calls to syncCloudIntegrations and use that to determine whether we should
// make the call or not.
let session =
options?.refreshIfExpired || options?.createIfNeeded || options?.forceNewSession
options?.refreshIfExpired || options?.createIfNeeded || options?.forceNewSession || options?.sync
? await this.fetchSession(descriptor)
: undefined;

Expand Down
45 changes: 31 additions & 14 deletions src/plus/integrations/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ export abstract class IntegrationBase<
forceSync = true;
}

await this.ensureSession({ createIfNeeded: forceSync });
// sync option, rather than createIfNeeded, makes sure we don't call connectCloudIntegrations and open a gkdev window
// if there was no session or some problem fetching/refreshing the existing session from the cloud api
await this.ensureSession({ sync: forceSync });
break;
case 'disconnected':
await this.disconnect({ silent: true });
Expand Down Expand Up @@ -295,16 +297,26 @@ export abstract class IntegrationBase<
}

@gate()
private async ensureSession(options: {
createIfNeeded?: boolean;
forceNewSession?: boolean;
source?: Sources;
}): Promise<ProviderAuthenticationSession | undefined> {
const { createIfNeeded, forceNewSession, source } = options;
private async ensureSession(
options:
| {
createIfNeeded?: boolean;
forceNewSession?: boolean;
sync?: never;
source?: Sources;
}
| {
createIfNeeded?: never;
forceNewSession?: never;
sync: boolean;
source?: Sources;
},
): Promise<ProviderAuthenticationSession | undefined> {
const { createIfNeeded, forceNewSession, source, sync } = options;
if (this._session != null) return this._session;
if (!configuration.get('integrations.enabled')) return undefined;

if (createIfNeeded) {
if (createIfNeeded || sync) {
await this.container.storage.deleteWorkspace(this.connectedKey);
} else if (this.container.storage.getWorkspace(this.connectedKey) === false) {
return undefined;
Expand All @@ -313,11 +325,16 @@ export abstract class IntegrationBase<
let session: ProviderAuthenticationSession | undefined | null;
try {
const authProvider = await this.authenticationService.get(this.authProvider.id);
session = await authProvider.getSession(this.authProviderDescriptor, {
createIfNeeded: createIfNeeded,
forceNewSession: forceNewSession,
source: source,
});
session = await authProvider.getSession(
this.authProviderDescriptor,
sync
? { sync: sync, source: source }
: {
createIfNeeded: createIfNeeded,
forceNewSession: forceNewSession,
source: source,
},
);
} catch (ex) {
await this.container.storage.deleteWorkspace(this.connectedKey);

Expand All @@ -328,7 +345,7 @@ export abstract class IntegrationBase<
session = null;
}

if (session === undefined && !createIfNeeded) {
if (session === undefined && !createIfNeeded && !sync) {
await this.container.storage.deleteWorkspace(this.connectedKey);
}

Expand Down
Loading