From 31116c0845d9cfdc19c60a8de41c352f8f5a0289 Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Mon, 27 Oct 2025 14:03:03 -0300 Subject: [PATCH 1/7] feat: getAuthenticatedUser endpoint --- CHANGELOG.md | 4 +++ graphql/schema.graphql | 5 ++++ graphql/types/Session.graphql | 18 +++++++++++++ node/clients/index.ts | 5 ++++ node/clients/vtexid.ts | 30 ++++++++++++++++++++++ node/globals.ts | 1 + node/resolvers/auth/index.ts | 8 +++++- node/resolvers/catalog/searchBreadcrumb.ts | 2 ++ 8 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 node/clients/vtexid.ts 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..b28672795 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: AuthenticatedUser @cacheControl(scope: PRIVATE) } type Mutation { diff --git a/graphql/types/Session.graphql b/graphql/types/Session.graphql index 87782a4ee..097e93ced 100644 --- a/graphql/types/Session.graphql +++ b/graphql/types/Session.graphql @@ -71,3 +71,21 @@ type SessionPickup { name: String address: Address } + +""" +Information about the authenticated user +""" +type AuthenticatedUser { + """ + User email + """ + user: String + """ + User ID + """ + userId: String + """ + User locale + """ + locale: 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..5381db1f6 --- /dev/null +++ b/node/clients/vtexid.ts @@ -0,0 +1,30 @@ +import { AppClient, InstanceOptions, IOContext } from '@vtex/api' + +export interface AuthenticatedUserResponse { + user: string + userId: string + locale: string +} + +export class VtexId extends AppClient { + private baseUrl = 'vtexid.vtex.com.br' + + constructor(ctx: IOContext, opts?: InstanceOptions) { + super('vtexid', ctx, opts) + } + + public getAuthenticatedUser = () => { + const { storeUserAuthToken = '' } = this.context + + if (!storeUserAuthToken) { + throw new Error('User is not authenticated') + } + + return this.http.get( + `http://${this.baseUrl}/api/vtexid/pub/authenticated/user?authToken=${storeUserAuthToken}`, + { + metric: 'vtexid-authenticated-user', + } + ) + } +} \ No newline at end of file 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..2b0f04cf6 100644 --- a/node/resolvers/auth/index.ts +++ b/node/resolvers/auth/index.ts @@ -3,7 +3,6 @@ import { stringify } from 'querystring' import { ResolverError, UserInputError } from '@vtex/api' import http, { Method } from 'axios' import { parse, serialize } from 'cookie' - import { withAuthToken } from '../headers' import paths from '../paths' import { GetLoginSessionsResponse } from './types' @@ -113,6 +112,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. diff --git a/node/resolvers/catalog/searchBreadcrumb.ts b/node/resolvers/catalog/searchBreadcrumb.ts index 7260cb669..4b88937fd 100644 --- a/node/resolvers/catalog/searchBreadcrumb.ts +++ b/node/resolvers/catalog/searchBreadcrumb.ts @@ -82,6 +82,8 @@ export const resolvers = { vtex: { account }, } = ctx + console.log('SearchBreadcrumb:name', { obj, ctx }) + const { queryUnit, mapUnit, index, queryArray, products } = obj const defaultName = queryArray[index] const isVtex = !Functions.isGoCommerceAcc(account) From 5f0c29dd243f032e7c760b46bd6ce7a4cee461f0 Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Mon, 27 Oct 2025 14:04:11 -0300 Subject: [PATCH 2/7] feat: getAuthenticatedUser endpoint --- node/resolvers/catalog/searchBreadcrumb.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/node/resolvers/catalog/searchBreadcrumb.ts b/node/resolvers/catalog/searchBreadcrumb.ts index 4b88937fd..7260cb669 100644 --- a/node/resolvers/catalog/searchBreadcrumb.ts +++ b/node/resolvers/catalog/searchBreadcrumb.ts @@ -82,8 +82,6 @@ export const resolvers = { vtex: { account }, } = ctx - console.log('SearchBreadcrumb:name', { obj, ctx }) - const { queryUnit, mapUnit, index, queryArray, products } = obj const defaultName = queryArray[index] const isVtex = !Functions.isGoCommerceAcc(account) From 3c34696aa07bcf575faf5e41eaecf389f6346281 Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Mon, 27 Oct 2025 14:13:10 -0300 Subject: [PATCH 3/7] lint fix --- node/clients/vtexid.ts | 2 +- node/resolvers/auth/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/node/clients/vtexid.ts b/node/clients/vtexid.ts index 5381db1f6..53058e9e3 100644 --- a/node/clients/vtexid.ts +++ b/node/clients/vtexid.ts @@ -27,4 +27,4 @@ export class VtexId extends AppClient { } ) } -} \ No newline at end of file +} diff --git a/node/resolvers/auth/index.ts b/node/resolvers/auth/index.ts index 2b0f04cf6..da3d18793 100644 --- a/node/resolvers/auth/index.ts +++ b/node/resolvers/auth/index.ts @@ -1,8 +1,8 @@ -import { stringify } from 'querystring' - import { ResolverError, UserInputError } from '@vtex/api' +import { stringify } from 'querystring' import http, { Method } from 'axios' import { parse, serialize } from 'cookie' + import { withAuthToken } from '../headers' import paths from '../paths' import { GetLoginSessionsResponse } from './types' From 890078565175941f4627344ab9d583b92188f12b Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Mon, 27 Oct 2025 14:17:49 -0300 Subject: [PATCH 4/7] lint fix --- node/resolvers/auth/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/resolvers/auth/index.ts b/node/resolvers/auth/index.ts index da3d18793..c35c117ec 100644 --- a/node/resolvers/auth/index.ts +++ b/node/resolvers/auth/index.ts @@ -1,5 +1,6 @@ -import { ResolverError, UserInputError } from '@vtex/api' import { stringify } from 'querystring' + +import { ResolverError, UserInputError } from '@vtex/api' import http, { Method } from 'axios' import { parse, serialize } from 'cookie' From e5be920960deb14aa756c61062b18bd61d9e28ee Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Fri, 7 Nov 2025 12:43:34 -0300 Subject: [PATCH 5/7] changed: vtexid api --- graphql/schema.graphql | 2 +- graphql/types/Session.graphql | 26 ++++++++++++++++++++++++++ node/clients/vtexid.ts | 15 +++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/graphql/schema.graphql b/graphql/schema.graphql index b28672795..aae2140cc 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -581,7 +581,7 @@ type Query { """ Returns information about the currently authenticated user """ - authenticatedUser: AuthenticatedUser @cacheControl(scope: PRIVATE) + authenticatedUser: AuthenticatedUserInfo @cacheControl(scope: PRIVATE) } type Mutation { diff --git a/graphql/types/Session.graphql b/graphql/types/Session.graphql index 097e93ced..12b04c73e 100644 --- a/graphql/types/Session.graphql +++ b/graphql/types/Session.graphql @@ -89,3 +89,29 @@ type AuthenticatedUser { """ locale: String } + +""" +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/vtexid.ts b/node/clients/vtexid.ts index 53058e9e3..c86c2b767 100644 --- a/node/clients/vtexid.ts +++ b/node/clients/vtexid.ts @@ -6,6 +6,14 @@ export interface AuthenticatedUserResponse { locale: string } +export interface AuthenticatedUserInfoResponse { + id: string + email: string + name: string + passwordLastUpdate: string | null + organizationUnit: string | null +} + export class VtexId extends AppClient { private baseUrl = 'vtexid.vtex.com.br' @@ -14,16 +22,19 @@ export class VtexId extends AppClient { } public getAuthenticatedUser = () => { - const { storeUserAuthToken = '' } = this.context + const { storeUserAuthToken = '', account } = this.context if (!storeUserAuthToken) { throw new Error('User is not authenticated') } return this.http.get( - `http://${this.baseUrl}/api/vtexid/pub/authenticated/user?authToken=${storeUserAuthToken}`, + `http://${this.baseUrl}/api/vtexid/user/info?an=${account}&scope=${account}`, { metric: 'vtexid-authenticated-user', + headers: { + Cookie: `VtexIdclientAutCookie_${account}=${storeUserAuthToken}`, + }, } ) } From a14c3673e34c7482ae4714bcc0880fc3eb3bbec8 Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Mon, 1 Dec 2025 15:45:56 -0300 Subject: [PATCH 6/7] changed: vtexid endpoint to janus client --- graphql/types/Session.graphql | 18 ------------------ node/clients/vtexid.ts | 28 +++++++++++----------------- 2 files changed, 11 insertions(+), 35 deletions(-) diff --git a/graphql/types/Session.graphql b/graphql/types/Session.graphql index 12b04c73e..d43890911 100644 --- a/graphql/types/Session.graphql +++ b/graphql/types/Session.graphql @@ -72,24 +72,6 @@ type SessionPickup { address: Address } -""" -Information about the authenticated user -""" -type AuthenticatedUser { - """ - User email - """ - user: String - """ - User ID - """ - userId: String - """ - User locale - """ - locale: String -} - """ Detailed information about the authenticated user from VTEX ID """ diff --git a/node/clients/vtexid.ts b/node/clients/vtexid.ts index c86c2b767..d75a0a5c5 100644 --- a/node/clients/vtexid.ts +++ b/node/clients/vtexid.ts @@ -1,4 +1,4 @@ -import { AppClient, InstanceOptions, IOContext } from '@vtex/api' +import { JanusClient } from '@vtex/api' export interface AuthenticatedUserResponse { user: string @@ -14,13 +14,7 @@ export interface AuthenticatedUserInfoResponse { organizationUnit: string | null } -export class VtexId extends AppClient { - private baseUrl = 'vtexid.vtex.com.br' - - constructor(ctx: IOContext, opts?: InstanceOptions) { - super('vtexid', ctx, opts) - } - +export class VtexId extends JanusClient { public getAuthenticatedUser = () => { const { storeUserAuthToken = '', account } = this.context @@ -28,14 +22,14 @@ export class VtexId extends AppClient { throw new Error('User is not authenticated') } - return this.http.get( - `http://${this.baseUrl}/api/vtexid/user/info?an=${account}&scope=${account}`, - { - metric: 'vtexid-authenticated-user', - headers: { - Cookie: `VtexIdclientAutCookie_${account}=${storeUserAuthToken}`, - }, - } - ) + return this.http.get(`/api/vtexid/user/info`, { + metric: 'vtexid-authenticated-user', + headers: { + Cookie: `VtexIdclientAutCookie_${account}=${storeUserAuthToken}`, + }, + params: { + scope: account, + }, + }) } } From b6a55e5ab189296fbc60c9049af948d486f811ec Mon Sep 17 00:00:00 2001 From: Iago Espinoza Date: Tue, 16 Dec 2025 10:18:49 -0300 Subject: [PATCH 7/7] removed unused interface --- node/clients/vtexid.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/node/clients/vtexid.ts b/node/clients/vtexid.ts index d75a0a5c5..7fe3df05e 100644 --- a/node/clients/vtexid.ts +++ b/node/clients/vtexid.ts @@ -6,14 +6,6 @@ export interface AuthenticatedUserResponse { locale: string } -export interface AuthenticatedUserInfoResponse { - id: string - email: string - name: string - passwordLastUpdate: string | null - organizationUnit: string | null -} - export class VtexId extends JanusClient { public getAuthenticatedUser = () => { const { storeUserAuthToken = '', account } = this.context