diff --git a/CHANGELOG.md b/CHANGELOG.md index 7075103ad..f9466260e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- getAuthenticatedUser endpoint + ## [2.173.2] - 2025-07-31 ## [2.173.2] - 2025-07-28 diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 17cb650e0..aae2140cc 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -577,6 +577,11 @@ type Query { salesChannel: String postalCode: String ): [SKU] @cacheControl(scope: SEGMENT, maxAge: SHORT) @withSegment + + """ + Returns information about the currently authenticated user + """ + authenticatedUser: AuthenticatedUserInfo @cacheControl(scope: PRIVATE) } type Mutation { diff --git a/graphql/types/Session.graphql b/graphql/types/Session.graphql index 87782a4ee..d43890911 100644 --- a/graphql/types/Session.graphql +++ b/graphql/types/Session.graphql @@ -71,3 +71,29 @@ type SessionPickup { name: String address: Address } + +""" +Detailed information about the authenticated user from VTEX ID +""" +type AuthenticatedUserInfo { + """ + User unique identifier + """ + id: String + """ + User email address + """ + email: String + """ + User display name + """ + name: String + """ + Date when password was last updated + """ + passwordLastUpdate: String + """ + Organization unit the user belongs to + """ + organizationUnit: String +} diff --git a/node/clients/index.ts b/node/clients/index.ts index f6daea378..ef94629ef 100644 --- a/node/clients/index.ts +++ b/node/clients/index.ts @@ -3,6 +3,7 @@ import { IOClients } from '@vtex/api' import { CallCenterOperator } from './callCenterOperator' import { Catalog } from './catalog' import { Checkout } from './checkout' +import { VtexId } from './vtexid' import { PvtCheckout } from './PvtCheckout' import { MasterData } from './masterdata' import { ProfileClient } from './profile' @@ -71,4 +72,8 @@ export class Clients extends IOClients { public get rewriter() { return this.getOrSet('rewriter', Rewriter) } + + public get vtexId() { + return this.getOrSet('vtexId', VtexId) + } } diff --git a/node/clients/vtexid.ts b/node/clients/vtexid.ts new file mode 100644 index 000000000..7fe3df05e --- /dev/null +++ b/node/clients/vtexid.ts @@ -0,0 +1,27 @@ +import { JanusClient } from '@vtex/api' + +export interface AuthenticatedUserResponse { + user: string + userId: string + locale: string +} + +export class VtexId extends JanusClient { + public getAuthenticatedUser = () => { + const { storeUserAuthToken = '', account } = this.context + + if (!storeUserAuthToken) { + throw new Error('User is not authenticated') + } + + return this.http.get(`/api/vtexid/user/info`, { + metric: 'vtexid-authenticated-user', + headers: { + Cookie: `VtexIdclientAutCookie_${account}=${storeUserAuthToken}`, + }, + params: { + scope: account, + }, + }) + } +} diff --git a/node/globals.ts b/node/globals.ts index 13fb72e0b..a94af9e8f 100644 --- a/node/globals.ts +++ b/node/globals.ts @@ -24,6 +24,7 @@ declare global { } interface CustomIOContext extends IOContext { + getAuthenticatedUser(): unknown currentProfile: CurrentProfile segment?: SegmentData orderFormId?: string diff --git a/node/resolvers/auth/index.ts b/node/resolvers/auth/index.ts index a4cdfcf62..c35c117ec 100644 --- a/node/resolvers/auth/index.ts +++ b/node/resolvers/auth/index.ts @@ -113,6 +113,13 @@ const checkPasswordFormat = (password: any) => { } export const queries = { + /** + * Get information about the currently authenticated user + */ + authenticatedUser: async (_: any, __: any, ctx: any) => { + return ctx.clients.vtexId.getAuthenticatedUser() + }, + /** * Request to the VTEX ID API the list of available login * options to the user authentication.