diff --git a/backend/src/controllers/v2/usersController.ts b/backend/src/controllers/v2/usersController.ts
index b5849f2e7..0c78d7667 100644
--- a/backend/src/controllers/v2/usersController.ts
+++ b/backend/src/controllers/v2/usersController.ts
@@ -81,25 +81,62 @@ export const updateMyMfaEnabled = async (req: Request, res: Response) => {
}
/**
- * Update the current user's name [firstName, lastName].
+ * Update name of the current user to [firstName, lastName].
* @param req
* @param res
* @returns
*/
export const updateName = async (req: Request, res: Response) => {
- const { firstName, lastName }: { firstName: string; lastName: string; } = req.body;
- req.user.firstName = firstName;
- req.user.lastName = lastName || "";
+ const {
+ firstName,
+ lastName
+ }: {
+ firstName: string;
+ lastName: string;
+ } = req.body;
- await req.user.save();
-
- const user = req.user;
+ const user = await User.findByIdAndUpdate(
+ req.user._id.toString(),
+ {
+ firstName,
+ lastName: lastName ?? ""
+ },
+ {
+ new: true
+ }
+ );
return res.status(200).send({
user,
});
}
+/**
+ * Update auth provider of the current user to [authProvider]
+ * @param req
+ * @param res
+ * @returns
+ */
+export const updateAuthProvider = async (req: Request, res: Response) => {
+ const {
+ authProvider
+ } = req.body;
+
+ const user = await User.findByIdAndUpdate(
+ req.user._id.toString(),
+ {
+ authProvider
+ },
+ {
+ new: true
+ }
+ );
+
+ return res.status(200).send({
+ user
+ });
+}
+
/**
* Return organizations that the current user is part of.
* @param req
diff --git a/backend/src/controllers/v3/authController.ts b/backend/src/controllers/v3/authController.ts
index 7a70f171c..7cb3cfd97 100644
--- a/backend/src/controllers/v3/authController.ts
+++ b/backend/src/controllers/v3/authController.ts
@@ -56,7 +56,7 @@ export const login1 = async (req: Request, res: Response) => {
if (!user) throw new Error("Failed to find user");
- if (user.authProvider) {
+ if (user.authProvider && user.authProvider !== AuthProvider.EMAIL) {
await validateProviderAuthToken({
email,
user,
@@ -117,7 +117,7 @@ export const login2 = async (req: Request, res: Response) => {
if (!user) throw new Error("Failed to find user");
- if (user.authProvider) {
+ if (user.authProvider && user.authProvider !== AuthProvider.EMAIL) {
await validateProviderAuthToken({
email,
user,
diff --git a/backend/src/models/user.ts b/backend/src/models/user.ts
index 68f2965c6..6559b1b7e 100644
--- a/backend/src/models/user.ts
+++ b/backend/src/models/user.ts
@@ -1,6 +1,7 @@
import { Document, Schema, Types, model } from "mongoose";
export enum AuthProvider {
+ EMAIL = "email",
GOOGLE = "google",
OKTA_SAML = "okta-saml"
}
diff --git a/backend/src/routes/v2/users.ts b/backend/src/routes/v2/users.ts
index 7815513ec..ca27d5b57 100644
--- a/backend/src/routes/v2/users.ts
+++ b/backend/src/routes/v2/users.ts
@@ -10,6 +10,9 @@ import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
} from "../../variables";
+import {
+ AuthProvider
+} from "../../models";
router.get(
"/me",
@@ -34,11 +37,25 @@ router.patch(
requireAuth({
acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
}),
- body("firstName").exists(),
+ body("firstName").exists().isString(),
+ body("lastName").isString(),
validateRequest,
usersController.updateName
);
+router.patch(
+ "/me/auth-provider",
+ requireAuth({
+ acceptedAuthModes: [AUTH_MODE_JWT, AUTH_MODE_API_KEY],
+ }),
+ body("authProvider").exists().isString().isIn([
+ AuthProvider.EMAIL,
+ AuthProvider.GOOGLE
+ ]),
+ validateRequest,
+ usersController.updateAuthProvider
+);
+
router.get(
"/me/organizations",
requireAuth({
diff --git a/frontend/public/locales/en/translations.json b/frontend/public/locales/en/translations.json
index e4c671ca4..a70a7dd8b 100644
--- a/frontend/public/locales/en/translations.json
+++ b/frontend/public/locales/en/translations.json
@@ -227,7 +227,7 @@
},
"password": {
"password": "Password",
- "change": "Change password",
+ "change": "Change Password",
"current": "Current password",
"current-wrong": "The current password may be wrong",
"new": "New password",
diff --git a/frontend/src/hooks/api/users/index.tsx b/frontend/src/hooks/api/users/index.tsx
index e1e530443..0c00810e5 100644
--- a/frontend/src/hooks/api/users/index.tsx
+++ b/frontend/src/hooks/api/users/index.tsx
@@ -13,4 +13,6 @@ export {
useLogoutUser,
useRegisterUserAction,
useRevokeMySessions,
- useUpdateOrgUserRole} from "./queries";
+ useUpdateOrgUserRole,
+ useUpdateUserAuthProvider
+} from "./queries";
diff --git a/frontend/src/hooks/api/users/queries.tsx b/frontend/src/hooks/api/users/queries.tsx
index fe9efd73f..19504217e 100644
--- a/frontend/src/hooks/api/users/queries.tsx
+++ b/frontend/src/hooks/api/users/queries.tsx
@@ -58,6 +58,27 @@ export const useRenameUser = () => {
});
};
+export const useUpdateUserAuthProvider = () => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: async ({
+ authProvider
+ }: {
+ authProvider: string;
+ }) => {
+ const { data: { user } } = await apiRequest.patch("/api/v2/users/me/auth-provider", {
+ authProvider
+ });
+
+ return user;
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries(userKeys.getUser);
+ }
+ });
+};
+
export const useGetUserAction = (action: string) =>
useQuery({
queryKey: userKeys.userAction,
diff --git a/frontend/src/hooks/api/users/types.ts b/frontend/src/hooks/api/users/types.ts
index 31a33c756..0c312b2b6 100644
--- a/frontend/src/hooks/api/users/types.ts
+++ b/frontend/src/hooks/api/users/types.ts
@@ -1,11 +1,18 @@
import { UserWsKeyPair } from "../keys/types";
+export enum AuthProvider {
+ EMAIL = "email",
+ GOOGLE = "google",
+ OKTA_SAML = "okta-saml"
+}
+
export type User = {
createdAt: Date;
updatedAt: Date;
email?: string;
firstName?: string;
lastName?: string;
+ authProvider?: AuthProvider;
encryptionVersion?: number;
protectedKey?: string;
protectedKeyIV?: string;
diff --git a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx
index 86a6c4b5e..abc6adf56 100644
--- a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx
+++ b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx
@@ -2,8 +2,8 @@ import { FormEvent, useState } from "react";
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { useRouter } from "next/router";
-// import { faGoogle } from "@fortawesome/free-brands-svg-icons";
-// import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faGoogle } from "@fortawesome/free-brands-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import axios from "axios"
import Error from "@app/components/basic/Error";
@@ -159,7 +159,7 @@ export const InitialStep = ({
or
- {/*
+
-
*/}
+