From 1204b51e64ff2564d29bd3f846c84f57ab43a065 Mon Sep 17 00:00:00 2001 From: BuzzLightyear <11892559+swift1337@users.noreply.github.com> Date: Tue, 1 Aug 2023 23:54:34 +0300 Subject: [PATCH 1/2] fix(auth): google auth (#27) * Fix record duplicate when logging with Google * Codegen fix --- internal/db/repository/users.sql.go | 17 +++++++++++------ internal/service/user/service_google.go | 4 +++- .../create_b_s_c_transaction_parameters.go | 8 +++----- .../create_b_s_c_transaction_responses.go | 6 ++---- pkg/api-kms/v1/client/wallet/wallet_client.go | 14 +++++++------- scripts/queries/users.sql | 9 +++++---- 6 files changed, 31 insertions(+), 27 deletions(-) diff --git a/internal/db/repository/users.sql.go b/internal/db/repository/users.sql.go index 3d6bb84..dd45cf1 100644 --- a/internal/db/repository/users.sql.go +++ b/internal/db/repository/users.sql.go @@ -194,26 +194,31 @@ func (q *Queries) ListUsers(ctx context.Context) ([]User, error) { const updateUser = `-- name: UpdateUser :one UPDATE users -SET name = $1, - profile_image_url= $2, - updated_at = $3 -WHERE id = $4 +SET name = $2, + profile_image_url= $3, + google_id = CASE WHEN $6::boolean THEN $4 ELSE users.google_id END, + updated_at = $5 +WHERE id = $1 RETURNING id, name, email, uuid, google_id, profile_image_url, created_at, updated_at, deleted_at, settings, password ` type UpdateUserParams struct { + ID int64 Name string ProfileImageUrl sql.NullString + GoogleID sql.NullString UpdatedAt time.Time - ID int64 + SetGoogleID bool } func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error) { row := q.db.QueryRow(ctx, updateUser, + arg.ID, arg.Name, arg.ProfileImageUrl, + arg.GoogleID, arg.UpdatedAt, - arg.ID, + arg.SetGoogleID, ) var i User err := row.Scan( diff --git a/internal/service/user/service_google.go b/internal/service/user/service_google.go index 2bb6b90..2b8ee81 100644 --- a/internal/service/user/service_google.go +++ b/internal/service/user/service_google.go @@ -15,7 +15,7 @@ import ( ) func (s *Service) ResolveWithGoogle(ctx context.Context, user *auth.GoogleUser) (*User, error) { - entry, err := s.store.GetUserByGoogleID(ctx, repository.StringToNullable(user.Sub)) + entry, err := s.store.GetUserByEmail(ctx, user.Email) switch { case errors.Is(err, pgx.ErrNoRows): return s.registerGoogleUser(ctx, user) @@ -57,6 +57,8 @@ func (s *Service) registerGoogleUser(ctx context.Context, user *auth.GoogleUser) func (s *Service) updateGoogleUser(ctx context.Context, userID int64, user *auth.GoogleUser) (*User, error) { entry, err := s.store.UpdateUser(ctx, repository.UpdateUserParams{ ID: userID, + SetGoogleID: true, + GoogleID: repository.StringToNullable(user.Sub), Name: user.Name, ProfileImageUrl: repository.StringToNullable(user.Picture), UpdatedAt: time.Now(), diff --git a/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_parameters.go b/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_parameters.go index e25e00a..64e5aa4 100644 --- a/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_parameters.go +++ b/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_parameters.go @@ -54,12 +54,10 @@ func NewCreateBSCTransactionParamsWithHTTPClient(client *http.Client) *CreateBSC } } -/* -CreateBSCTransactionParams contains all the parameters to send to the API endpoint +/* CreateBSCTransactionParams contains all the parameters to send to the API endpoint + for the create b s c transaction operation. - for the create b s c transaction operation. - - Typically these are written to a http.Request. + Typically these are written to a http.Request. */ type CreateBSCTransactionParams struct { diff --git a/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_responses.go b/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_responses.go index fd4a0f7..f169ae5 100644 --- a/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_responses.go +++ b/pkg/api-kms/v1/client/wallet/create_b_s_c_transaction_responses.go @@ -45,8 +45,7 @@ func NewCreateBSCTransactionCreated() *CreateBSCTransactionCreated { return &CreateBSCTransactionCreated{} } -/* - CreateBSCTransactionCreated describes a response with status code 201, with default header values. +/* CreateBSCTransactionCreated describes a response with status code 201, with default header values. Transaction Created */ @@ -78,8 +77,7 @@ func NewCreateBSCTransactionBadRequest() *CreateBSCTransactionBadRequest { return &CreateBSCTransactionBadRequest{} } -/* - CreateBSCTransactionBadRequest describes a response with status code 400, with default header values. +/* CreateBSCTransactionBadRequest describes a response with status code 400, with default header values. Validation error / Not found */ diff --git a/pkg/api-kms/v1/client/wallet/wallet_client.go b/pkg/api-kms/v1/client/wallet/wallet_client.go index 0e60c17..cd7856b 100644 --- a/pkg/api-kms/v1/client/wallet/wallet_client.go +++ b/pkg/api-kms/v1/client/wallet/wallet_client.go @@ -48,7 +48,7 @@ type ClientService interface { } /* -CreateBSCTransaction creates b s c transaction + CreateBSCTransaction creates b s c transaction */ func (a *Client) CreateBSCTransaction(params *CreateBSCTransactionParams, opts ...ClientOption) (*CreateBSCTransactionCreated, error) { // TODO: Validate the params before sending @@ -86,7 +86,7 @@ func (a *Client) CreateBSCTransaction(params *CreateBSCTransactionParams, opts . } /* -CreateEthereumTransaction creates ethereum transaction + CreateEthereumTransaction creates ethereum transaction */ func (a *Client) CreateEthereumTransaction(params *CreateEthereumTransactionParams, opts ...ClientOption) (*CreateEthereumTransactionCreated, error) { // TODO: Validate the params before sending @@ -124,7 +124,7 @@ func (a *Client) CreateEthereumTransaction(params *CreateEthereumTransactionPara } /* -CreateMaticTransaction creates polygon transaction + CreateMaticTransaction creates polygon transaction */ func (a *Client) CreateMaticTransaction(params *CreateMaticTransactionParams, opts ...ClientOption) (*CreateMaticTransactionCreated, error) { // TODO: Validate the params before sending @@ -162,7 +162,7 @@ func (a *Client) CreateMaticTransaction(params *CreateMaticTransactionParams, op } /* -CreateTronTransaction creates tron transaction + CreateTronTransaction creates tron transaction */ func (a *Client) CreateTronTransaction(params *CreateTronTransactionParams, opts ...ClientOption) (*CreateTronTransactionCreated, error) { // TODO: Validate the params before sending @@ -200,7 +200,7 @@ func (a *Client) CreateTronTransaction(params *CreateTronTransactionParams, opts } /* -CreateWallet creates wallet + CreateWallet creates wallet */ func (a *Client) CreateWallet(params *CreateWalletParams, opts ...ClientOption) (*CreateWalletCreated, error) { // TODO: Validate the params before sending @@ -238,7 +238,7 @@ func (a *Client) CreateWallet(params *CreateWalletParams, opts ...ClientOption) } /* -DeleteWallet deletes wallet + DeleteWallet deletes wallet */ func (a *Client) DeleteWallet(params *DeleteWalletParams, opts ...ClientOption) (*DeleteWalletNoContent, error) { // TODO: Validate the params before sending @@ -276,7 +276,7 @@ func (a *Client) DeleteWallet(params *DeleteWalletParams, opts ...ClientOption) } /* -GetWallet gets wallet + GetWallet gets wallet */ func (a *Client) GetWallet(params *GetWalletParams, opts ...ClientOption) (*GetWalletOK, error) { // TODO: Validate the params before sending diff --git a/scripts/queries/users.sql b/scripts/queries/users.sql index 343f85e..9f00e24 100644 --- a/scripts/queries/users.sql +++ b/scripts/queries/users.sql @@ -31,10 +31,11 @@ RETURNING *; -- name: UpdateUser :one UPDATE users -SET name = $1, - profile_image_url= $2, - updated_at = $3 -WHERE id = $4 +SET name = $2, + profile_image_url= $3, + google_id = CASE WHEN @set_google_id::boolean THEN $4 ELSE users.google_id END, + updated_at = $5 +WHERE id = $1 RETURNING *; -- name: UpdateUserPassword :one From dd7169e072c81b949fff7b5e0a15d95ac5f018d8 Mon Sep 17 00:00:00 2001 From: thefirefox <57635195+wtfthefirefox@users.noreply.github.com> Date: Thu, 17 Aug 2023 18:35:40 +0300 Subject: [PATCH 2/2] Fix login page (#28) * added fix * added loading state to all pages --- ui-dashboard/src/app.tsx | 21 +++++++++++++--- .../src/pages/login-page/login-page.tsx | 24 +++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/ui-dashboard/src/app.tsx b/ui-dashboard/src/app.tsx index 927f9a5..56d56c8 100644 --- a/ui-dashboard/src/app.tsx +++ b/ui-dashboard/src/app.tsx @@ -98,6 +98,7 @@ const App: React.FC = () => { const [user, setUser] = React.useState(); const [isSupportFormOpen, setIsSupportFormOpen] = React.useState(false); const [isFormSubmitting, setIsFormSubmitting] = React.useState(false); + const [isLoading, setIsLoading] = React.useState(true); const loadUserInfo = async () => { let newMerchantId = merchantId; @@ -112,7 +113,11 @@ const App: React.FC = () => { posthog?.reset(true); } - navigate("/login"); + navigate("/login", { + state: { + isNeedLogout: true + } + }); } } }; @@ -127,7 +132,11 @@ const App: React.FC = () => { posthog?.reset(true); } - navigate("/login"); + navigate("/login", { + state: { + isNeedLogout: true + } + }); } } }; @@ -154,6 +163,7 @@ const App: React.FC = () => { if (!newMerchantId) return; await getMerchant(newMerchantId); + setIsLoading(false); }; await getCookie(); @@ -210,7 +220,11 @@ const App: React.FC = () => { } await authProvider.logout(); - navigate("/login"); + navigate("/login", { + state: { + isNeedLogout: true + } + }); }; const userMenu: MenuProps["items"] = [ @@ -277,6 +291,7 @@ const App: React.FC = () => { )} } + loading={isLoading} actionsRender={() => { return [ !isManageMerchantsActive ? ( diff --git a/ui-dashboard/src/pages/login-page/login-page.tsx b/ui-dashboard/src/pages/login-page/login-page.tsx index 14a8f60..5116ebd 100644 --- a/ui-dashboard/src/pages/login-page/login-page.tsx +++ b/ui-dashboard/src/pages/login-page/login-page.tsx @@ -1,7 +1,8 @@ import "./login-page.scss"; import * as React from "react"; -import {useNavigate} from "react-router-dom"; +import {AxiosError} from "axios"; +import {useNavigate, useLocation} from "react-router-dom"; import {Modal, Button, Typography, Form, Input, notification} from "antd"; import {GoogleOutlined, CheckOutlined} from "@ant-design/icons"; import logoImg from "/fav/android-chrome-192x192.png"; @@ -15,12 +16,17 @@ import SpinWithMask from "src/components/spin-with-mask/spin-with-mask"; const b = bevis("login-page"); +interface LoginState { + isNeedLogout: boolean; +} + const LoginPage: React.FC = () => { const [form] = Form.useForm(); const [api, contextHolder] = notification.useNotification(); const [isFormSubmitting, setIsFormSubmitting] = React.useState(false); const [providersList, setProvidersList] = React.useState([]); const navigate = useNavigate(); + const state: LoginState = useLocation().state; const openNotification = (title: string, description: string) => { api.info({ @@ -60,7 +66,21 @@ const LoginPage: React.FC = () => { useMount(async () => { window.addEventListener("popstate", () => navigate("/login", {replace: true})); - localStorage.remove("merchantId"); + + if (state?.isNeedLogout) { + localStorage.remove("merchantId"); + } else { + try { + await authProvider.getCookie(); + await authProvider.getMe(); + navigate("/"); + } catch (e) { + if (e instanceof AxiosError && e.response?.status === 401) { + localStorage.remove("merchantId"); + } + } + } + const availProviders = await authProvider.getProviders(); setProvidersList(availProviders ?? []); });