diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index f33456bd5..762e22e54 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -468,7 +468,7 @@ export const registerRoutes = async ( projectMembershipDAL }); - const loginService = authLoginServiceFactory({ userDAL, smtpService, tokenService, orgDAL, tokenDAL: authTokenDAL }); + const loginService = authLoginServiceFactory({ userDAL, smtpService, tokenService, orgDAL }); const passwordService = authPaswordServiceFactory({ tokenService, smtpService, diff --git a/backend/src/server/routes/v3/login-router.ts b/backend/src/server/routes/v3/login-router.ts index 61a0c74e5..b5f523a54 100644 --- a/backend/src/server/routes/v3/login-router.ts +++ b/backend/src/server/routes/v3/login-router.ts @@ -42,7 +42,8 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => { }, schema: { body: z.object({ - organizationId: z.string().trim() + organizationId: z.string().trim(), + userAgent: z.enum(["cli"]).optional() }), response: { 200: z.object({ @@ -53,7 +54,7 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => { handler: async (req, res) => { const cfg = getConfig(); const tokens = await server.services.login.selectOrganization({ - userAgent: req.headers["user-agent"], + userAgent: req.body.userAgent ?? req.headers["user-agent"], authJwtToken: req.headers.authorization, organizationId: req.body.organizationId, ipAddress: req.realIp diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 91bf40198..fb38c024e 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -12,7 +12,6 @@ import { BadRequestError, DatabaseError, UnauthorizedError } from "@app/lib/erro import { logger } from "@app/lib/logger"; import { getServerCfg } from "@app/services/super-admin/super-admin-service"; -import { TTokenDALFactory } from "../auth-token/auth-token-dal"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TokenType } from "../auth-token/auth-token-types"; import { TOrgDALFactory } from "../org/org-dal"; @@ -34,7 +33,6 @@ type TAuthLoginServiceFactoryDep = { orgDAL: TOrgDALFactory; tokenService: TAuthTokenServiceFactory; smtpService: TSmtpService; - tokenDAL: TTokenDALFactory; }; export type TAuthLoginFactory = ReturnType; @@ -42,8 +40,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService, - orgDAL, - tokenDAL + orgDAL }: TAuthLoginServiceFactoryDep) => { /* * Private @@ -376,8 +373,6 @@ export const authLoginServiceFactory = ({ }); } - await tokenDAL.incrementTokenSessionVersion(user.id, decodedToken.tokenVersionId); - const tokens = await generateUserTokens({ authMethod: decodedToken.authMethod, user, diff --git a/frontend/src/hooks/api/auth/queries.tsx b/frontend/src/hooks/api/auth/queries.tsx index fcec4f2ef..27c7c87d2 100644 --- a/frontend/src/hooks/api/auth/queries.tsx +++ b/frontend/src/hooks/api/auth/queries.tsx @@ -24,6 +24,7 @@ import { SRP1DTO, SRPR1Res, TOauthTokenExchangeDTO, + UserAgentType, VerifyMfaTokenDTO, VerifyMfaTokenRes, VerifySignupInviteDTO @@ -60,7 +61,10 @@ export const useLogin1 = () => { }); }; -export const selectOrganization = async (data: { organizationId: string }) => { +export const selectOrganization = async (data: { + organizationId: string; + userAgent?: UserAgentType; +}) => { const { data: res } = await apiRequest.post<{ token: string }>( "/api/v3/auth/select-organization", data @@ -71,11 +75,14 @@ export const selectOrganization = async (data: { organizationId: string }) => { export const useSelectOrganization = () => { const queryClient = useQueryClient(); return useMutation({ - mutationFn: async (details: { organizationId: string }) => { + mutationFn: async (details: { organizationId: string; userAgent?: UserAgentType }) => { const data = await selectOrganization(details); - SecurityClient.setToken(data.token); - SecurityClient.setProviderAuthToken(""); + // If a custom user agent is set, then this session is meant for another consuming application, not the web application. + if (!details.userAgent) { + SecurityClient.setToken(data.token); + SecurityClient.setProviderAuthToken(""); + } return data; }, diff --git a/frontend/src/hooks/api/auth/types.ts b/frontend/src/hooks/api/auth/types.ts index 3664e8e96..f51f7b091 100644 --- a/frontend/src/hooks/api/auth/types.ts +++ b/frontend/src/hooks/api/auth/types.ts @@ -145,3 +145,7 @@ export type IssueBackupPrivateKeyDTO = { export type GetBackupEncryptedPrivateKeyDTO = { verificationToken: string; }; + +export enum UserAgentType { + CLI = "cli" +} diff --git a/frontend/src/pages/login/select-organization.tsx b/frontend/src/pages/login/select-organization.tsx index cf953664d..13ec3e414 100644 --- a/frontend/src/pages/login/select-organization.tsx +++ b/frontend/src/pages/login/select-organization.tsx @@ -16,6 +16,7 @@ import { Button, Spinner } from "@app/components/v2"; import { SessionStorageKeys } from "@app/const"; import { useUser } from "@app/context"; import { useGetOrganizations, useLogoutUser, useSelectOrganization } from "@app/hooks/api"; +import { UserAgentType } from "@app/hooks/api/auth/types"; import { Organization } from "@app/hooks/api/types"; import { getAuthToken, isLoggedIn } from "@app/reactQuery"; import { navigateUserToOrg } from "@app/views/Login/Login.utils"; @@ -68,7 +69,10 @@ export default function LoginPage() { return; } - const { token } = await selectOrg.mutateAsync({ organizationId: organization.id }); + const { token } = await selectOrg.mutateAsync({ + organizationId: organization.id, + userAgent: callbackPort ? UserAgentType.CLI : undefined + }); if (callbackPort) { const privateKey = localStorage.getItem("PRIVATE_KEY");