Skip to content

Commit 67b579f

Browse files
committed
updates
1 parent bb30829 commit 67b579f

File tree

1 file changed

+146
-142
lines changed

1 file changed

+146
-142
lines changed

src/auth/AuthManager.ts

Lines changed: 146 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,162 @@
1-
import * as vscode from 'vscode';
1+
import * as vscode from "vscode";
22

33
export class AuthManager {
4-
private static readonly TOKEN_KEY = 'codegen.token';
5-
private static readonly ORG_ID_KEY = 'codegen.orgId';
6-
7-
constructor(private context: vscode.ExtensionContext) {}
8-
9-
async login(): Promise<void> {
10-
// Show login options
11-
const loginMethod = await vscode.window.showQuickPick([
12-
{
13-
label: '🌐 Login with Browser',
14-
description: 'Open codegen.com in your browser to authenticate',
15-
detail: 'Recommended - secure OAuth flow'
16-
},
17-
{
18-
label: '🔑 Enter API Token',
19-
description: 'Manually enter your API token',
20-
detail: 'For users who already have a token'
21-
}
22-
], {
23-
placeHolder: 'Choose how you want to authenticate with Codegen',
24-
ignoreFocusOut: true
25-
});
26-
27-
if (!loginMethod) {
28-
return;
29-
}
30-
31-
if (loginMethod.label.includes('Browser')) {
32-
await this.loginWithBrowser();
33-
} else {
34-
await this.loginWithToken();
35-
}
4+
private static readonly TOKEN_KEY = "codegen.token";
5+
private static readonly ORG_ID_KEY = "codegen.orgId";
6+
7+
constructor(private context: vscode.ExtensionContext) {}
8+
9+
async login(): Promise<void> {
10+
// Show login options
11+
const loginMethod = await vscode.window.showQuickPick(
12+
[
13+
{
14+
label: "🌐 Login with Browser",
15+
description: "Open codegen.com in your browser to authenticate",
16+
detail: "Recommended - secure OAuth flow",
17+
},
18+
{
19+
label: "🔑 Enter API Token",
20+
description: "Manually enter your API token",
21+
detail: "For users who already have a token",
22+
},
23+
],
24+
{
25+
placeHolder: "Choose how you want to authenticate with Codegen",
26+
ignoreFocusOut: true,
27+
}
28+
);
29+
30+
if (!loginMethod) {
31+
return;
3632
}
3733

38-
private async loginWithBrowser(): Promise<void> {
39-
try {
40-
// Generate a unique state parameter for security
41-
const state = Math.random().toString(36).substring(2, 15);
42-
43-
// Construct the OAuth URL
44-
const config = vscode.workspace.getConfiguration('codegen');
45-
const baseUrl = config.get('webUrl', 'https://codegen.com');
46-
const authUrl = `${baseUrl}/auth/vscode?state=${state}`;
47-
48-
// Open the browser
49-
vscode.env.openExternal(vscode.Uri.parse(authUrl));
50-
51-
// Show a message to the user
52-
const result = await vscode.window.showInformationMessage(
53-
'Opening codegen.com in your browser for authentication...',
54-
{ modal: false },
55-
'I\'ve completed authentication',
56-
'Cancel'
57-
);
58-
59-
if (result === 'Cancel') {
60-
return;
61-
}
62-
63-
if (result === 'I\'ve completed authentication') {
64-
// Prompt for the token that should now be available
65-
const token = await vscode.window.showInputBox({
66-
prompt: 'Paste the API token from your browser',
67-
placeHolder: 'The token should be displayed after authentication',
68-
password: true,
69-
ignoreFocusOut: true
70-
});
71-
72-
if (token) {
73-
await this.storeTokenAndValidate(token);
74-
}
75-
}
76-
} catch (error) {
77-
vscode.window.showErrorMessage(`Browser login failed: ${error}`);
78-
throw error;
79-
}
34+
if (loginMethod.label.includes("Browser")) {
35+
await this.loginWithBrowser();
36+
} else {
37+
await this.loginWithToken();
8038
}
81-
82-
private async loginWithToken(): Promise<void> {
39+
}
40+
41+
private async loginWithBrowser(): Promise<void> {
42+
try {
43+
// Construct the CLI token URL
44+
const config = vscode.workspace.getConfiguration("codegen");
45+
const baseUrl = config.get("webUrl", "https://codegen.com");
46+
const authUrl = `${baseUrl}/cli-token`;
47+
48+
// Open the browser
49+
vscode.env.openExternal(vscode.Uri.parse(authUrl));
50+
51+
// Show a message to the user
52+
const result = await vscode.window.showInformationMessage(
53+
"Opening codegen.com in your browser for authentication...",
54+
{ modal: false },
55+
"I've completed authentication",
56+
"Cancel"
57+
);
58+
59+
if (result === "Cancel") {
60+
return;
61+
}
62+
63+
if (result === "I've completed authentication") {
64+
// Prompt for the token that should now be available
8365
const token = await vscode.window.showInputBox({
84-
prompt: 'Enter your Codegen API token',
85-
placeHolder: 'Your API token from codegen.com/settings',
86-
password: true,
87-
ignoreFocusOut: true
66+
prompt: "Paste the API token from your browser",
67+
placeHolder: "The token should be displayed after authentication",
68+
password: true,
69+
ignoreFocusOut: true,
8870
});
8971

90-
if (!token) {
91-
return;
92-
}
93-
94-
await this.storeTokenAndValidate(token);
95-
}
96-
97-
private async storeTokenAndValidate(token: string): Promise<void> {
98-
// Store the token securely
99-
await this.context.secrets.store(AuthManager.TOKEN_KEY, token);
100-
101-
// Try to get organization info
102-
try {
103-
const orgId = await this.fetchOrgId(token);
104-
if (orgId) {
105-
await this.context.globalState.update(AuthManager.ORG_ID_KEY, orgId);
106-
}
107-
108-
vscode.window.showInformationMessage('Successfully logged in to Codegen! 🎉');
109-
} catch (error) {
110-
vscode.window.showErrorMessage(`Login failed: ${error}`);
111-
// Clear the token if login failed
112-
await this.context.secrets.delete(AuthManager.TOKEN_KEY);
113-
throw error;
72+
if (token) {
73+
await this.storeTokenAndValidate(token);
11474
}
75+
}
76+
} catch (error) {
77+
vscode.window.showErrorMessage(`Browser login failed: ${error}`);
78+
throw error;
11579
}
116-
117-
async logout(): Promise<void> {
118-
await this.context.secrets.delete(AuthManager.TOKEN_KEY);
119-
await this.context.globalState.update(AuthManager.ORG_ID_KEY, undefined);
120-
vscode.window.showInformationMessage('Successfully logged out from Codegen');
80+
}
81+
82+
private async loginWithToken(): Promise<void> {
83+
const token = await vscode.window.showInputBox({
84+
prompt: "Enter your Codegen API token",
85+
placeHolder: "Your API token from codegen.com/settings",
86+
password: true,
87+
ignoreFocusOut: true,
88+
});
89+
90+
if (!token) {
91+
return;
12192
}
12293

123-
async getToken(): Promise<string | undefined> {
124-
return await this.context.secrets.get(AuthManager.TOKEN_KEY);
94+
await this.storeTokenAndValidate(token);
95+
}
96+
97+
private async storeTokenAndValidate(token: string): Promise<void> {
98+
// Store the token securely
99+
await this.context.secrets.store(AuthManager.TOKEN_KEY, token);
100+
101+
// Try to get organization info
102+
try {
103+
const orgId = await this.fetchOrgId(token);
104+
if (orgId) {
105+
await this.context.globalState.update(AuthManager.ORG_ID_KEY, orgId);
106+
}
107+
108+
vscode.window.showInformationMessage(
109+
"Successfully logged in to Codegen! 🎉"
110+
);
111+
} catch (error) {
112+
vscode.window.showErrorMessage(`Login failed: ${error}`);
113+
// Clear the token if login failed
114+
await this.context.secrets.delete(AuthManager.TOKEN_KEY);
115+
throw error;
125116
}
126-
127-
getOrgId(): number | undefined {
128-
return this.context.globalState.get(AuthManager.ORG_ID_KEY);
129-
}
130-
131-
isAuthenticated(): boolean {
132-
// We can't await here, so we check if we have stored credentials
133-
// The actual validation happens when making API calls
134-
return this.context.globalState.get(AuthManager.ORG_ID_KEY) !== undefined;
117+
}
118+
119+
async logout(): Promise<void> {
120+
await this.context.secrets.delete(AuthManager.TOKEN_KEY);
121+
await this.context.globalState.update(AuthManager.ORG_ID_KEY, undefined);
122+
vscode.window.showInformationMessage(
123+
"Successfully logged out from Codegen"
124+
);
125+
}
126+
127+
async getToken(): Promise<string | undefined> {
128+
return await this.context.secrets.get(AuthManager.TOKEN_KEY);
129+
}
130+
131+
getOrgId(): number | undefined {
132+
return this.context.globalState.get(AuthManager.ORG_ID_KEY);
133+
}
134+
135+
isAuthenticated(): boolean {
136+
// We can't await here, so we check if we have stored credentials
137+
// The actual validation happens when making API calls
138+
return this.context.globalState.get(AuthManager.ORG_ID_KEY) !== undefined;
139+
}
140+
141+
private async fetchOrgId(token: string): Promise<number | undefined> {
142+
const config = vscode.workspace.getConfiguration("codegen");
143+
const apiEndpoint = config.get("apiEndpoint", "https://api.codegen.com");
144+
145+
// This is a simplified version - in a real implementation, you'd make an API call
146+
// to get the user's organization information
147+
// For now, we'll use a default org ID or prompt the user
148+
149+
const orgIdInput = await vscode.window.showInputBox({
150+
prompt: "Enter your organization ID (optional)",
151+
placeHolder: "Leave empty to use default organization",
152+
ignoreFocusOut: true,
153+
});
154+
155+
if (orgIdInput && !isNaN(Number(orgIdInput))) {
156+
return Number(orgIdInput);
135157
}
136158

137-
private async fetchOrgId(token: string): Promise<number | undefined> {
138-
const config = vscode.workspace.getConfiguration('codegen');
139-
const apiEndpoint = config.get('apiEndpoint', 'https://api.codegen.com');
140-
141-
// This is a simplified version - in a real implementation, you'd make an API call
142-
// to get the user's organization information
143-
// For now, we'll use a default org ID or prompt the user
144-
145-
const orgIdInput = await vscode.window.showInputBox({
146-
prompt: 'Enter your organization ID (optional)',
147-
placeHolder: 'Leave empty to use default organization',
148-
ignoreFocusOut: true
149-
});
150-
151-
if (orgIdInput && !isNaN(Number(orgIdInput))) {
152-
return Number(orgIdInput);
153-
}
154-
155-
// Return a default org ID or undefined
156-
return undefined;
157-
}
159+
// Return a default org ID or undefined
160+
return undefined;
161+
}
158162
}

0 commit comments

Comments
 (0)