Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
3ad08325
Commit
3ad08325
authored
Sep 10, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: use user v2 api in frontend
parent
93f062d0
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
205 additions
and
168 deletions
+205
-168
user_service.go
api/v2/user_service.go
+2
-2
user_service.proto
proto/api/v2/user_service.proto
+5
-3
README.md
proto/gen/api/v2/README.md
+1
-1
user_service.pb.go
proto/gen/api/v2/user_service.pb.go
+118
-125
user_service.pb.gw.go
proto/gen/api/v2/user_service.pb.gw.go
+18
-20
ChangePasswordDialog.tsx
web/src/components/ChangePasswordDialog.tsx
+9
-4
MyAccountSection.tsx
web/src/components/Settings/MyAccountSection.tsx
+10
-7
useCurrentUser.ts
web/src/hooks/useCurrentUser.ts
+19
-0
user.ts
web/src/store/v1/user.ts
+18
-1
user_service_pb.d.ts
web/src/types/proto/api/v2/user_service_pb.d.ts
+3
-3
user_service_pb.js
web/src/types/proto/api/v2/user_service_pb.js
+2
-2
No files found.
api/v2/user_service.go
View file @
3ad08325
...
...
@@ -66,7 +66,7 @@ func (s *UserService) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUse
if
currentUser
==
nil
||
(
currentUser
.
ID
!=
userID
&&
currentUser
.
Role
!=
store
.
RoleAdmin
)
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"permission denied"
)
}
if
request
.
UpdateMask
==
nil
||
len
(
request
.
UpdateMask
.
Paths
)
==
0
{
if
request
.
UpdateMask
==
nil
||
len
(
request
.
UpdateMask
)
==
0
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"update mask is empty"
)
}
...
...
@@ -75,7 +75,7 @@ func (s *UserService) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUse
ID
:
userID
,
UpdatedTs
:
&
currentTs
,
}
for
_
,
path
:=
range
request
.
UpdateMask
.
Paths
{
for
_
,
path
:=
range
request
.
UpdateMask
{
if
path
==
"username"
{
update
.
Username
=
&
request
.
User
.
Username
}
else
if
path
==
"nickname"
{
...
...
proto/api/v2/user_service.proto
View file @
3ad08325
...
...
@@ -7,7 +7,6 @@ import "api/v2/memo_service.proto";
import
"google/api/annotations.proto"
;
import
"google/api/client.proto"
;
import
"google/api/field_behavior.proto"
;
import
"google/protobuf/field_mask.proto"
;
import
"google/protobuf/timestamp.proto"
;
option
go_package
=
"gen/api/v2"
;
...
...
@@ -18,7 +17,10 @@ service UserService {
option
(
google.api.method_signature
)
=
"username"
;
}
rpc
UpdateUser
(
UpdateUserRequest
)
returns
(
UpdateUserResponse
)
{
option
(
google.api.http
)
=
{
patch
:
"/api/v2/users/{username}"
};
option
(
google.api.http
)
=
{
post
:
"/api/v2/users/{username}"
body
:
"*"
};
option
(
google.api.method_signature
)
=
"username"
;
}
}
...
...
@@ -68,7 +70,7 @@ message UpdateUserRequest {
User
user
=
2
;
// The update mask applies to the user resource.
google.protobuf.FieldMask
update_mask
=
3
;
repeated
string
update_mask
=
3
;
}
message
UpdateUserResponse
{
...
...
proto/gen/api/v2/README.md
View file @
3ad08325
...
...
@@ -429,7 +429,7 @@
| ----- | ---- | ----- | ----------- |
| username |
[
string
](
#string
)
| | |
| user |
[
User
](
#memos-api-v2-User
)
| | |
| update_mask |
[
google.protobuf.FieldMask
](
#google-protobuf-FieldMask
)
|
| The update mask applies to the user resource. |
| update_mask |
[
string
](
#string
)
| repeated
| The update mask applies to the user resource. |
...
...
proto/gen/api/v2/user_service.pb.go
View file @
3ad08325
This diff is collapsed.
Click to expand it.
proto/gen/api/v2/user_service.pb.gw.go
View file @
3ad08325
...
...
@@ -83,14 +83,18 @@ func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime.
}
var
(
filter_UserService_UpdateUser_0
=
&
utilities
.
DoubleArray
{
Encoding
:
map
[
string
]
int
{
"username"
:
0
},
Base
:
[]
int
{
1
,
2
,
0
,
0
},
Check
:
[]
int
{
0
,
1
,
2
,
2
}}
)
func
request_UserService_UpdateUser_0
(
ctx
context
.
Context
,
marshaler
runtime
.
Marshaler
,
client
UserServiceClient
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
(
proto
.
Message
,
runtime
.
ServerMetadata
,
error
)
{
var
protoReq
UpdateUserRequest
var
metadata
runtime
.
ServerMetadata
newReader
,
berr
:=
utilities
.
IOReaderFactory
(
req
.
Body
)
if
berr
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
berr
)
}
if
err
:=
marshaler
.
NewDecoder
(
newReader
())
.
Decode
(
&
protoReq
);
err
!=
nil
&&
err
!=
io
.
EOF
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
var
(
val
string
ok
bool
...
...
@@ -108,13 +112,6 @@ func request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Mar
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"type mismatch, parameter: %s, error: %v"
,
"username"
,
err
)
}
if
err
:=
req
.
ParseForm
();
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
if
err
:=
runtime
.
PopulateQueryParameters
(
&
protoReq
,
req
.
Form
,
filter_UserService_UpdateUser_0
);
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
msg
,
err
:=
client
.
UpdateUser
(
ctx
,
&
protoReq
,
grpc
.
Header
(
&
metadata
.
HeaderMD
),
grpc
.
Trailer
(
&
metadata
.
TrailerMD
))
return
msg
,
metadata
,
err
...
...
@@ -124,6 +121,14 @@ func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runti
var
protoReq
UpdateUserRequest
var
metadata
runtime
.
ServerMetadata
newReader
,
berr
:=
utilities
.
IOReaderFactory
(
req
.
Body
)
if
berr
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
berr
)
}
if
err
:=
marshaler
.
NewDecoder
(
newReader
())
.
Decode
(
&
protoReq
);
err
!=
nil
&&
err
!=
io
.
EOF
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
var
(
val
string
ok
bool
...
...
@@ -141,13 +146,6 @@ func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runti
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"type mismatch, parameter: %s, error: %v"
,
"username"
,
err
)
}
if
err
:=
req
.
ParseForm
();
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
if
err
:=
runtime
.
PopulateQueryParameters
(
&
protoReq
,
req
.
Form
,
filter_UserService_UpdateUser_0
);
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
msg
,
err
:=
server
.
UpdateUser
(
ctx
,
&
protoReq
)
return
msg
,
metadata
,
err
...
...
@@ -184,7 +182,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux
.
Handle
(
"P
ATCH
"
,
pattern_UserService_UpdateUser_0
,
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
{
mux
.
Handle
(
"P
OST
"
,
pattern_UserService_UpdateUser_0
,
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
{
ctx
,
cancel
:=
context
.
WithCancel
(
req
.
Context
())
defer
cancel
()
var
stream
runtime
.
ServerTransportStream
...
...
@@ -272,7 +270,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux
.
Handle
(
"P
ATCH
"
,
pattern_UserService_UpdateUser_0
,
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
{
mux
.
Handle
(
"P
OST
"
,
pattern_UserService_UpdateUser_0
,
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
{
ctx
,
cancel
:=
context
.
WithCancel
(
req
.
Context
())
defer
cancel
()
inboundMarshaler
,
outboundMarshaler
:=
runtime
.
MarshalerForRequest
(
mux
,
req
)
...
...
web/src/components/ChangePasswordDialog.tsx
View file @
3ad08325
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useGlobalStore
,
useUserStore
}
from
"@/store/module"
;
import
{
useUserV1Store
}
from
"@/store/v1"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
generateDialog
}
from
"./Dialog"
;
import
Icon
from
"./Icon"
;
...
...
@@ -10,6 +11,7 @@ type Props = DialogProps;
const
ChangePasswordDialog
:
React
.
FC
<
Props
>
=
({
destroy
}:
Props
)
=>
{
const
t
=
useTranslate
();
const
userStore
=
useUserStore
();
const
userV1Store
=
useUserV1Store
();
const
globalStore
=
useGlobalStore
();
const
profile
=
globalStore
.
state
.
systemStatus
.
profile
;
const
[
newPassword
,
setNewPassword
]
=
useState
(
""
);
...
...
@@ -50,10 +52,13 @@ const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
try
{
const
user
=
userStore
.
getState
().
user
as
User
;
await
userStore
.
patchUser
({
id
:
user
.
id
,
password
:
newPassword
,
});
await
userV1Store
.
updateUser
(
{
username
:
user
.
username
,
password
:
newPassword
,
},
[
"password"
]
);
toast
.
success
(
t
(
"message.password-changed"
));
handleCloseBtnClick
();
}
catch
(
error
:
any
)
{
...
...
web/src/components/Settings/MyAccountSection.tsx
View file @
3ad08325
import
{
Button
,
Input
,
Textarea
}
from
"@mui/joy"
;
import
{
useUserStore
}
from
"@/store/module"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useUserV1Store
}
from
"@/store/v1"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
showChangePasswordDialog
from
"../ChangePasswordDialog"
;
import
{
showCommonDialog
}
from
"../Dialog/CommonDialog"
;
...
...
@@ -9,8 +10,8 @@ import UserAvatar from "../UserAvatar";
const
MyAccountSection
=
()
=>
{
const
t
=
useTranslate
();
const
user
Store
=
useUser
Store
();
const
user
=
use
rStore
.
state
.
user
as
User
;
const
user
V1Store
=
useUserV1
Store
();
const
user
=
use
CurrentUser
()
;
const
openAPIRoute
=
`
${
window
.
location
.
origin
}
/api/v1/memo?openId=
${
user
.
openId
}
`
;
const
handleResetOpenIdBtnClick
=
async
()
=>
{
...
...
@@ -20,10 +21,12 @@ const MyAccountSection = () => {
style
:
"warning"
,
dialogName
:
"reset-openid-dialog"
,
onConfirm
:
async
()
=>
{
await
userStore
.
patchUser
({
id
:
user
.
id
,
resetOpenId
:
true
,
});
await
userV1Store
.
updateUser
(
{
username
:
user
.
username
,
},
[
"reset_open_id"
]
);
},
});
};
...
...
web/src/hooks/useCurrentUser.ts
0 → 100644
View file @
3ad08325
import
{
useEffect
}
from
"react"
;
import
{
useUserStore
}
from
"@/store/module"
;
import
{
useUserV1Store
}
from
"@/store/v1"
;
const
useCurrentUser
=
()
=>
{
const
userStore
=
useUserStore
();
const
userV1Store
=
useUserV1Store
();
const
currentUsername
=
userStore
.
getCurrentUsername
();
useEffect
(()
=>
{
if
(
currentUsername
)
{
userV1Store
.
getOrFetchUserByUsername
(
currentUsername
);
}
},
[
currentUsername
]);
return
userV1Store
.
getUserByUsername
(
currentUsername
);
};
export
default
useCurrentUser
;
web/src/store/v1/user.ts
View file @
3ad08325
import
axios
from
"axios"
;
import
{
create
}
from
"zustand"
;
import
*
as
api
from
"@/helpers/api"
;
import
{
User
}
from
"@/types/proto/api/v2/user_service_pb"
;
import
{
U
pdateUserResponse
,
U
ser
}
from
"@/types/proto/api/v2/user_service_pb"
;
interface
UserV1Store
{
userMapByUsername
:
Record
<
string
,
User
>
;
getOrFetchUserByUsername
:
(
username
:
string
)
=>
Promise
<
User
>
;
getUserByUsername
:
(
username
:
string
)
=>
User
;
updateUser
:
(
user
:
Partial
<
User
>
,
updateMask
:
string
[])
=>
Promise
<
User
>
;
}
// Request cache is used to prevent multiple requests.
...
...
@@ -39,6 +41,21 @@ const useUserV1Store = create<UserV1Store>()((set, get) => ({
const
userMap
=
get
().
userMapByUsername
;
return
userMap
[
username
]
as
User
;
},
updateUser
:
async
(
user
:
Partial
<
User
>
,
updateMask
:
string
[])
=>
{
const
{
data
:
{
user
:
updatedUser
},
}
=
await
axios
.
post
<
UpdateUserResponse
>
(
`/api/v2/users/
${
user
.
username
}
`
,
{
user
,
updateMask
,
});
if
(
!
updatedUser
)
{
throw
new
Error
(
"User not found"
);
}
const
userMap
=
get
().
userMapByUsername
;
userMap
[
updatedUser
.
username
]
=
updatedUser
;
set
(
userMap
);
return
updatedUser
;
},
}));
export
default
useUserV1Store
;
web/src/types/proto/api/v2/user_service_pb.d.ts
View file @
3ad08325
...
...
@@ -3,7 +3,7 @@
/* eslint-disable */
// @ts-nocheck
import
type
{
BinaryReadOptions
,
FieldList
,
FieldMask
,
JsonReadOptions
,
JsonValue
,
PartialMessage
,
PlainMessage
,
Timestamp
}
from
"@bufbuild/protobuf"
;
import
type
{
BinaryReadOptions
,
FieldList
,
JsonReadOptions
,
JsonValue
,
PartialMessage
,
PlainMessage
,
Timestamp
}
from
"@bufbuild/protobuf"
;
import
{
Message
,
proto3
}
from
"@bufbuild/protobuf"
;
import
type
{
RowStatus
}
from
"./common_pb.js"
;
import
type
{
Visibility
}
from
"./memo_service_pb.js"
;
...
...
@@ -172,9 +172,9 @@ export declare class UpdateUserRequest extends Message<UpdateUserRequest> {
/**
* The update mask applies to the user resource.
*
* @generated from field:
google.protobuf.FieldMask
update_mask = 3;
* @generated from field:
repeated string
update_mask = 3;
*/
updateMask
?:
FieldMask
;
updateMask
:
string
[]
;
constructor
(
data
?:
PartialMessage
<
UpdateUserRequest
>
);
...
...
web/src/types/proto/api/v2/user_service_pb.js
View file @
3ad08325
...
...
@@ -3,7 +3,7 @@
/* eslint-disable */
// @ts-nocheck
import
{
FieldMask
,
proto3
,
Timestamp
}
from
"@bufbuild/protobuf"
;
import
{
proto3
,
Timestamp
}
from
"@bufbuild/protobuf"
;
import
{
RowStatus
}
from
"./common_pb.js"
;
import
{
Visibility
}
from
"./memo_service_pb.js"
;
...
...
@@ -68,7 +68,7 @@ export const UpdateUserRequest = proto3.makeMessageType(
()
=>
[
{
no
:
1
,
name
:
"username"
,
kind
:
"scalar"
,
T
:
9
/* ScalarType.STRING */
},
{
no
:
2
,
name
:
"user"
,
kind
:
"message"
,
T
:
User
},
{
no
:
3
,
name
:
"update_mask"
,
kind
:
"
message"
,
T
:
FieldMask
},
{
no
:
3
,
name
:
"update_mask"
,
kind
:
"
scalar"
,
T
:
9
/* ScalarType.STRING */
,
repeated
:
true
},
],
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment