Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 1x 1x 1x 3x 3x 3x 3x 4x 1x 1x 1x 2x 2x 2x 2x 2x 4x 1x 1x 1x 1x 1x 1x 4x 4x 1x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import {
getAuthContext,
signInOrUpMenu,
signOutMenu,
} from "../services/auth-service";
import * as vscode from "vscode";
import { getUserByID } from "../api/user-api";
import { setAuthContext } from "../services/auth-service";
import {
errorNotification,
showAuthNotification,
} from "../views/notifications";
/**
* Registers the command to trigger the Sign In or Sign Up menu.
*/
export const signInCommand = vscode.commands.registerCommand(
"collabAgent.signIn",
async () => signInOrUpMenu()
);
/**
* Registers the command to trigger the Sign Out flow.
*/
export const signOutCommand = vscode.commands.registerCommand(
"collabAgent.signOut",
async () => signOutMenu()
);
/**
* Handles URIs sent back to the extension after OAuth authentication flow.
* Supports both custom backend auth and Supabase OAuth callbacks.
*
* @param uri - The URI containing authentication data
*/
export const handleAuthUri = async (uri: vscode.Uri) => {
if (uri.path === "/auth-complete") {
const urlParams = new URLSearchParams(uri.query);
const token = urlParams.get("id"); // Extract token
if (!token) {
await errorNotification("No token found in URL.");
return;
}
try {
const { user, error } = await getUserByID(token);
if (error || !user) {
await errorNotification(`Failed to get user data: ${error}`);
return;
}
user.isAuthenticated = true;
const { error: authError } = await setAuthContext(user);
if (authError) {
await errorNotification(`Failed to set user context: ${authError}`);
return;
}
await showAuthNotification(`Sign In successfully! 🎉`);
vscode.commands.executeCommand("collabAgent.authStateChanged");
} catch (err: any) {
await errorNotification(`Unexpected error: ${err.message}`);
}
}
if (uri.path === "/auth/callback") {
try {
const { getSupabase } = require("../auth/supabaseClient");
const supabase = getSupabase();
// Supabase sends tokens in the fragment (#) for OAuth redirect flows
if (uri.fragment) {
const frag = new URLSearchParams(uri.fragment.replace(/^#/, ""));
const access_token = frag.get("access_token");
const refresh_token = frag.get("refresh_token");
if (access_token) {
try {
await supabase.auth.setSession({ access_token, refresh_token: refresh_token || "" });
} catch (e:any) {
await errorNotification(`Failed to set Supabase session: ${e.message}`);
}
}
}
const { data: { user }, error } = await supabase.auth.getUser();
if (error) {
await errorNotification(`Supabase auth error: ${error.message}`);
return;
}
if (!user) {
await errorNotification("No Supabase user in session.");
return;
}
const minimalUser = {
id: user.id,
email: user.email || "",
first_name: user.user_metadata?.name || user.email?.split("@")[0] || "",
last_name: "",
isLocked: false,
isAuthenticated: true,
userStatus: "ACTIVE",
role: "user",
settings: {
bug_percentage: 0,
show_notifications: true,
give_suggestions: true,
enable_quiz: false,
active_threshold: 0,
suspend_threshold: 0,
pass_rate: 0,
suspend_rate: 0
}
} as any;
const { setAuthContext } = require("../services/auth-service");
const { error: ctxErr } = await setAuthContext(minimalUser);
if (ctxErr) {
await errorNotification(`Failed to set auth context: ${ctxErr}`);
return;
}
await showAuthNotification(`Signed in as ${minimalUser.email}`);
vscode.commands.executeCommand("collabAgent.authStateChanged");
} catch (e: any) {
await errorNotification(`OAuth callback failed: ${e.message}`);
}
}
};
/** URI handler command for processing authentication callbacks */
export const uriHandlerCommand = vscode.window.registerUriHandler({
handleUri: handleAuthUri,
});
/**
* Creates and manages the authentication status bar item for the extension.
*
* Dynamically updates the status bar based on the user's authentication state.
*
* @param context - The extension context for managing command subscriptions.
* @returns A `StatusBarItem` representing the authentication action (sign in or sign out).
*/
export function createAuthStatusBarItem(context: vscode.ExtensionContext) {
const authStatusBarItem = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Right,
100
);
authStatusBarItem.name = "Collab Agent Authentication";
authStatusBarItem.backgroundColor = new vscode.ThemeColor(
"statusBarItem.errorBackground"
);
authStatusBarItem.show();
const updateAuthStatus = async () => {
const { context: user } = await getAuthContext();
if (user?.isAuthenticated) {
authStatusBarItem.text = `$(sign-out) Sign Out`;
authStatusBarItem.tooltip = `Signed in as ${user.email}`;
authStatusBarItem.command = "collabAgent.signOut";
authStatusBarItem.backgroundColor = new vscode.ThemeColor(
"statusBarItem.errorBackground"
);
} else {
authStatusBarItem.text = `$(key) Sign in with GitHub`;
authStatusBarItem.tooltip = "Authenticate with GitHub";
authStatusBarItem.command = "collabAgent.signIn";
authStatusBarItem.backgroundColor = new vscode.ThemeColor(
"statusBarItem.warningBackground"
);
}
};
updateAuthStatus();
context.subscriptions.push(
authStatusBarItem,
vscode.commands.registerCommand("collabAgent.showAuthOptions", async () => {
// Temporarily commenting out email and sign-up options - only GitHub OAuth is active
// const choice = await vscode.window.showQuickPick(
// ["Sign In with GitHub", "Sign In with Email", "Sign Up"],
// { placeHolder: "Select authentication method" }
// );
// if (choice === "Sign In with GitHub") {
// vscode.commands.executeCommand("collabAgent.githubLogin");
// } else if (choice === "Sign In with Email") {
// vscode.commands.executeCommand("collabAgent.emailLogin");
// } else if (choice === "Sign Up") {
// vscode.commands.executeCommand("collabAgent.signUp");
// }
// Directly call GitHub sign-in
vscode.commands.executeCommand("collabAgent.signIn");
}),
vscode.commands.registerCommand("collabAgent.authStateChanged", updateAuthStatus)
);
return authStatusBarItem;
}
/**
* Registers all authentication-related commands with VS Code.
*/
export function registerAuthCommands() {
vscode.commands.registerCommand("collabAgent.signIn", async () => signInOrUpMenu());
vscode.commands.registerCommand("collabAgent.signOut", async () => signOutMenu());
vscode.commands.registerCommand("collabAgent.authStateChanged", async () => {
const item = createAuthStatusBarItem({ subscriptions: [] } as any);
item.show();
});
vscode.window.registerUriHandler({ handleUri: handleAuthUri });
}
|