diff --git a/.github/agents/git-master.agent.md b/.github/agents/git-master.agent.md deleted file mode 100644 index 148bfb1..0000000 --- a/.github/agents/git-master.agent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -description: 'Describe what this custom agent does and when to use it.' -tools: ['vscode', 'launch', 'edit', 'read', 'search', 'web', 'shell', 'agents', 'github.vscode-pull-request-github/copilotCodingAgent', 'github.vscode-pull-request-github/issue_fetch', 'github.vscode-pull-request-github/suggest-fix', 'github.vscode-pull-request-github/searchSyntax', 'github.vscode-pull-request-github/doSearch', 'github.vscode-pull-request-github/renderIssues', 'github.vscode-pull-request-github/activePullRequest', 'github.vscode-pull-request-github/openPullRequest', 'todo'] ---- -Define what this custom agent accomplishes for the user, when to use it, and the edges it won't cross. Specify its ideal inputs/outputs, the tools it may call, and how it reports progress or asks for help. diff --git a/packages/backend/src/routes/auth/index.ts b/packages/backend/src/routes/auth/index.ts index 0610e6f..1c0c2d2 100644 --- a/packages/backend/src/routes/auth/index.ts +++ b/packages/backend/src/routes/auth/index.ts @@ -264,6 +264,7 @@ export const getAuthRouter = (serviceProvider: ServiceProvider) = email: userDoc.email, name: userDoc.name, avatar: userDoc.avatar, + verifiedAlias: userDoc.verifiedAlias, role: userDoc.role, providers: Object.keys(userDoc.providers), createdAt: userDoc.createdAt, diff --git a/packages/backend/src/services/oauth/oauth.service.ts b/packages/backend/src/services/oauth/oauth.service.ts index 9a828af..4e5018d 100644 --- a/packages/backend/src/services/oauth/oauth.service.ts +++ b/packages/backend/src/services/oauth/oauth.service.ts @@ -57,6 +57,7 @@ export const createOAuthService = ( email, name: profile.displayName || profile.username || email, avatar: profile.photos?.[0]?.value, + username: profile.username, // GitHub username for verified alias }); const expressUser: Express.User = { @@ -65,6 +66,7 @@ export const createOAuthService = ( email: userDoc.email, displayName: userDoc.name, avatar: userDoc.avatar, + verifiedAlias: userDoc.verifiedAlias, providers: userDoc.providers, role: userDoc.role, createdAt: userDoc.createdAt, @@ -126,6 +128,7 @@ export const createOAuthService = ( email: userDoc.email, displayName: userDoc.name, avatar: userDoc.avatar, + verifiedAlias: userDoc.verifiedAlias, providers: userDoc.providers, role: userDoc.role, createdAt: userDoc.createdAt, @@ -197,6 +200,7 @@ export const createOAuthService = ( email: userDoc.email, displayName: userDoc.name, avatar: userDoc.avatar, + verifiedAlias: userDoc.verifiedAlias, providers: userDoc.providers, role: userDoc.role, createdAt: userDoc.createdAt, @@ -244,6 +248,7 @@ export const createOAuthService = ( email: userDoc.email, displayName: userDoc.name, avatar: userDoc.avatar, + verifiedAlias: userDoc.verifiedAlias, providers: userDoc.providers, role: userDoc.role, createdAt: userDoc.createdAt, diff --git a/packages/backend/src/services/user/user.service.ts b/packages/backend/src/services/user/user.service.ts index 7d6299b..1bf869c 100644 --- a/packages/backend/src/services/user/user.service.ts +++ b/packages/backend/src/services/user/user.service.ts @@ -47,7 +47,7 @@ export const createUserService = (mongo: MongoService, logger: LoggerService): U }, async findOrCreateUser(profile: ProviderProfile): Promise { - const { provider, providerId, email, name, avatar } = profile; + const { provider, providerId, email, name, avatar, username } = profile; const db = mongo.getDb(); const collection = db.collection('users'); const normalizedEmail = email.toLowerCase(); @@ -60,13 +60,18 @@ export const createUserService = (mongo: MongoService, logger: LoggerService): U // If provider already linked and matches, just update last login if (providerData && providerData.id === providerId) { + const updateFields: any = { + lastLoginAt: new Date(), + updatedAt: new Date(), + }; + // Update verifiedAlias if username provided and not already set + if (username && !user.verifiedAlias) { + updateFields.verifiedAlias = username; + } await collection.updateOne( { _id: user._id! }, { - $set: { - lastLoginAt: new Date(), - updatedAt: new Date(), - }, + $set: updateFields, } ); @@ -77,24 +82,30 @@ export const createUserService = (mongo: MongoService, logger: LoggerService): U return { ...user, + verifiedAlias: username && !user.verifiedAlias ? username : user.verifiedAlias, lastLoginAt: new Date(), updatedAt: new Date(), }; } // Auto-link new provider to existing email + const autoLinkUpdate: any = { + [`providers.${provider}`]: { + id: providerId, + email: normalizedEmail, + connectedAt: new Date(), + }, + lastLoginAt: new Date(), + updatedAt: new Date(), + }; + // Set verifiedAlias if username provided and not already set + if (username && !user.verifiedAlias) { + autoLinkUpdate.verifiedAlias = username; + } await collection.updateOne( { _id: user._id! }, { - $set: { - [`providers.${provider}`]: { - id: providerId, - email: normalizedEmail, - connectedAt: new Date(), - }, - lastLoginAt: new Date(), - updatedAt: new Date(), - }, + $set: autoLinkUpdate, } ); @@ -114,6 +125,7 @@ export const createUserService = (mongo: MongoService, logger: LoggerService): U email: normalizedEmail, name: name || normalizedEmail.split('@')[0], avatar, + verifiedAlias: username, // Store verified alias from OAuth provider role: 'user', isActive: true, providers: { diff --git a/packages/backend/src/types/express.d.ts b/packages/backend/src/types/express.d.ts index 0d9bafb..80f17f8 100644 --- a/packages/backend/src/types/express.d.ts +++ b/packages/backend/src/types/express.d.ts @@ -18,6 +18,7 @@ declare global { email: string; displayName?: string; avatar?: string; + verifiedAlias?: string; // Verified username/alias from OAuth provider // Provider information providers?: { diff --git a/packages/frontend/src/lib/auth-api.ts b/packages/frontend/src/lib/auth-api.ts index 678d4a3..a93f6f6 100644 --- a/packages/frontend/src/lib/auth-api.ts +++ b/packages/frontend/src/lib/auth-api.ts @@ -13,6 +13,7 @@ export interface User { email: string; name: string; avatar?: string; + verifiedAlias?: string; // Verified username/alias from OAuth provider role: 'user' | 'admin'; providers: string[]; createdAt?: string; diff --git a/packages/shared/src/types/user.types.ts b/packages/shared/src/types/user.types.ts index 299f098..3186829 100644 --- a/packages/shared/src/types/user.types.ts +++ b/packages/shared/src/types/user.types.ts @@ -31,6 +31,7 @@ export interface UserDocument { email: string; name?: string; avatar?: string; + verifiedAlias?: string; // Verified username/alias from OAuth provider (e.g., GitHub username) role: 'user' | 'admin'; isActive: boolean; @@ -73,6 +74,7 @@ export interface ProviderProfile { email: string; name?: string; avatar?: string; + username?: string; // Provider-specific username/alias (e.g., GitHub username) } /** @@ -83,6 +85,7 @@ export interface UserApiResponse { email: string; name?: string; avatar?: string; + verifiedAlias?: string; role: 'user' | 'admin'; providers: string[]; // Just provider names, not IDs createdAt: string; @@ -124,7 +127,7 @@ export interface UserUiResponse { email: string; name: string; avatarUrl?: string; - githubUsername?: string; + verifiedAlias?: string; role: 'user' | 'admin'; createdAt: string; }