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
c5a5f67f
Commit
c5a5f67f
authored
Jan 29, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: migrate auth service
parent
de8db638
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
314 additions
and
106 deletions
+314
-106
acl_config.go
api/v2/acl_config.go
+4
-0
apidocs.swagger.yaml
api/v2/apidocs.swagger.yaml
+4
-0
auth_service.go
api/v2/auth_service.go
+210
-0
auth_service.proto
proto/api/v2/auth_service.proto
+1
-0
README.md
proto/gen/api/v2/README.md
+1
-0
auth_service.pb.go
proto/gen/api/v2/auth_service.pb.go
+80
-70
UserBanner.tsx
web/src/components/UserBanner.tsx
+2
-2
api.ts
web/src/helpers/api.ts
+0
-27
AuthCallback.tsx
web/src/pages/AuthCallback.tsx
+8
-4
SignIn.tsx
web/src/pages/SignIn.tsx
+2
-1
SignUp.tsx
web/src/pages/SignUp.tsx
+2
-2
No files found.
api/v2/acl_config.go
View file @
c5a5f67f
...
@@ -5,6 +5,10 @@ import "strings"
...
@@ -5,6 +5,10 @@ import "strings"
var
authenticationAllowlistMethods
=
map
[
string
]
bool
{
var
authenticationAllowlistMethods
=
map
[
string
]
bool
{
"/memos.api.v2.WorkspaceService/GetWorkspaceProfile"
:
true
,
"/memos.api.v2.WorkspaceService/GetWorkspaceProfile"
:
true
,
"/memos.api.v2.AuthService/GetAuthStatus"
:
true
,
"/memos.api.v2.AuthService/GetAuthStatus"
:
true
,
"/memos.api.v2.AuthService/SignIn"
:
true
,
"/memos.api.v2.AuthService/SignInWithSSO"
:
true
,
"/memos.api.v2.AuthService/SignOut"
:
true
,
"/memos.api.v2.AuthService/SignUp"
:
true
,
"/memos.api.v2.UserService/GetUser"
:
true
,
"/memos.api.v2.UserService/GetUser"
:
true
,
"/memos.api.v2.MemoService/ListMemos"
:
true
,
"/memos.api.v2.MemoService/ListMemos"
:
true
,
"/memos.api.v2.MemoService/GetMemo"
:
true
,
"/memos.api.v2.MemoService/GetMemo"
:
true
,
...
...
api/v2/apidocs.swagger.yaml
View file @
c5a5f67f
...
@@ -40,6 +40,10 @@ paths:
...
@@ -40,6 +40,10 @@ paths:
in
:
query
in
:
query
required
:
false
required
:
false
type
:
string
type
:
string
-
name
:
neverExpire
in
:
query
required
:
false
type
:
boolean
tags
:
tags
:
-
AuthService
-
AuthService
/api/v2/auth/signin/sso
:
/api/v2/auth/signin/sso
:
...
...
api/v2/auth_service.go
View file @
c5a5f67f
...
@@ -3,15 +3,25 @@ package v2
...
@@ -3,15 +3,25 @@ package v2
import
(
import
(
"context"
"context"
"fmt"
"fmt"
"regexp"
"time"
"github.com/pkg/errors"
"github.com/pkg/errors"
"golang.org/x/crypto/bcrypt"
"google.golang.org/grpc"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"github.com/usememos/memos/api/auth"
"github.com/usememos/memos/api/auth"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/plugin/idp"
"github.com/usememos/memos/plugin/idp/oauth2"
apiv2pb
"github.com/usememos/memos/proto/gen/api/v2"
apiv2pb
"github.com/usememos/memos/proto/gen/api/v2"
storepb
"github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/server/service/metric"
"github.com/usememos/memos/store"
)
)
func
(
s
*
APIV2Service
)
GetAuthStatus
(
ctx
context
.
Context
,
_
*
apiv2pb
.
GetAuthStatusRequest
)
(
*
apiv2pb
.
GetAuthStatusResponse
,
error
)
{
func
(
s
*
APIV2Service
)
GetAuthStatus
(
ctx
context
.
Context
,
_
*
apiv2pb
.
GetAuthStatusRequest
)
(
*
apiv2pb
.
GetAuthStatusResponse
,
error
)
{
...
@@ -31,6 +41,190 @@ func (s *APIV2Service) GetAuthStatus(ctx context.Context, _ *apiv2pb.GetAuthStat
...
@@ -31,6 +41,190 @@ func (s *APIV2Service) GetAuthStatus(ctx context.Context, _ *apiv2pb.GetAuthStat
},
nil
},
nil
}
}
func
(
s
*
APIV2Service
)
SignIn
(
ctx
context
.
Context
,
request
*
apiv2pb
.
SignInRequest
)
(
*
apiv2pb
.
SignInResponse
,
error
)
{
user
,
err
:=
s
.
Store
.
GetUser
(
ctx
,
&
store
.
FindUser
{
Username
:
&
request
.
Username
,
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to find user by username %s"
,
request
.
Username
))
}
if
user
==
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
fmt
.
Sprintf
(
"user not found with username %s"
,
request
.
Username
))
}
else
if
user
.
RowStatus
==
store
.
Archived
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
fmt
.
Sprintf
(
"user has been archived with username %s"
,
request
.
Username
))
}
// Compare the stored hashed password, with the hashed version of the password that was received.
if
err
:=
bcrypt
.
CompareHashAndPassword
([]
byte
(
user
.
PasswordHash
),
[]
byte
(
request
.
Password
));
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"unmatched email and password"
)
}
expireTime
:=
time
.
Now
()
.
Add
(
auth
.
AccessTokenDuration
)
if
request
.
NeverExpire
{
// Zero time means never expire.
expireTime
=
time
.
Time
{}
}
if
err
:=
s
.
doSignIn
(
ctx
,
user
,
expireTime
);
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to sign in, err: %s"
,
err
))
}
return
&
apiv2pb
.
SignInResponse
{
User
:
convertUserFromStore
(
user
),
},
nil
}
func
(
s
*
APIV2Service
)
SignInWithSSO
(
ctx
context
.
Context
,
request
*
apiv2pb
.
SignInWithSSORequest
)
(
*
apiv2pb
.
SignInWithSSOResponse
,
error
)
{
identityProvider
,
err
:=
s
.
Store
.
GetIdentityProvider
(
ctx
,
&
store
.
FindIdentityProvider
{
ID
:
&
request
.
IdpId
,
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to get identity provider, err: %s"
,
err
))
}
if
identityProvider
==
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
fmt
.
Sprintf
(
"identity provider not found with id %d"
,
request
.
IdpId
))
}
var
userInfo
*
idp
.
IdentityProviderUserInfo
if
identityProvider
.
Type
==
store
.
IdentityProviderOAuth2Type
{
oauth2IdentityProvider
,
err
:=
oauth2
.
NewIdentityProvider
(
identityProvider
.
Config
.
OAuth2Config
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to create oauth2 identity provider, err: %s"
,
err
))
}
token
,
err
:=
oauth2IdentityProvider
.
ExchangeToken
(
ctx
,
request
.
RedirectUri
,
request
.
Code
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to exchange token, err: %s"
,
err
))
}
userInfo
,
err
=
oauth2IdentityProvider
.
UserInfo
(
token
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to get user info, err: %s"
,
err
))
}
}
identifierFilter
:=
identityProvider
.
IdentifierFilter
if
identifierFilter
!=
""
{
identifierFilterRegex
,
err
:=
regexp
.
Compile
(
identifierFilter
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to compile identifier filter regex, err: %s"
,
err
))
}
if
!
identifierFilterRegex
.
MatchString
(
userInfo
.
Identifier
)
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
fmt
.
Sprintf
(
"identifier %s is not allowed"
,
userInfo
.
Identifier
))
}
}
user
,
err
:=
s
.
Store
.
GetUser
(
ctx
,
&
store
.
FindUser
{
Username
:
&
userInfo
.
Identifier
,
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to find user by username %s"
,
userInfo
.
Identifier
))
}
if
user
==
nil
{
userCreate
:=
&
store
.
User
{
Username
:
userInfo
.
Identifier
,
// The new signup user should be normal user by default.
Role
:
store
.
RoleUser
,
Nickname
:
userInfo
.
DisplayName
,
Email
:
userInfo
.
Email
,
}
password
,
err
:=
util
.
RandomString
(
20
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to generate random password, err: %s"
,
err
))
}
passwordHash
,
err
:=
bcrypt
.
GenerateFromPassword
([]
byte
(
password
),
bcrypt
.
DefaultCost
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to generate password hash, err: %s"
,
err
))
}
userCreate
.
PasswordHash
=
string
(
passwordHash
)
user
,
err
=
s
.
Store
.
CreateUser
(
ctx
,
userCreate
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to create user, err: %s"
,
err
))
}
}
if
user
.
RowStatus
==
store
.
Archived
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
fmt
.
Sprintf
(
"user has been archived with username %s"
,
userInfo
.
Identifier
))
}
if
err
:=
s
.
doSignIn
(
ctx
,
user
,
time
.
Now
()
.
Add
(
auth
.
AccessTokenDuration
));
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to sign in, err: %s"
,
err
))
}
return
&
apiv2pb
.
SignInWithSSOResponse
{
User
:
convertUserFromStore
(
user
),
},
nil
}
func
(
s
*
APIV2Service
)
doSignIn
(
ctx
context
.
Context
,
user
*
store
.
User
,
expireTime
time
.
Time
)
error
{
accessToken
,
err
:=
auth
.
GenerateAccessToken
(
user
.
Email
,
user
.
ID
,
expireTime
,
[]
byte
(
s
.
Secret
))
if
err
!=
nil
{
return
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to generate tokens, err: %s"
,
err
))
}
if
err
:=
s
.
UpsertAccessTokenToStore
(
ctx
,
user
,
accessToken
,
"user login"
);
err
!=
nil
{
return
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to upsert access token to store, err: %s"
,
err
))
}
cookieExpires
:=
time
.
Now
()
.
Add
(
auth
.
CookieExpDuration
)
if
expireTime
.
IsZero
()
{
// Set cookie expires to 100 years.
cookieExpires
=
time
.
Now
()
.
AddDate
(
100
,
0
,
0
)
}
if
err
:=
grpc
.
SetHeader
(
ctx
,
metadata
.
New
(
map
[
string
]
string
{
"Set-Cookie"
:
fmt
.
Sprintf
(
"%s=%s; Path=/; Expires=%s; HttpOnly; SameSite=Strict"
,
auth
.
AccessTokenCookieName
,
accessToken
,
cookieExpires
.
Format
(
time
.
RFC1123
)),
}));
err
!=
nil
{
return
status
.
Errorf
(
codes
.
Internal
,
"failed to set grpc header, error: %v"
,
err
)
}
metric
.
Enqueue
(
"user sign in"
)
return
nil
}
func
(
s
*
APIV2Service
)
SignUp
(
ctx
context
.
Context
,
request
*
apiv2pb
.
SignUpRequest
)
(
*
apiv2pb
.
SignUpResponse
,
error
)
{
workspaceGeneralSetting
,
err
:=
s
.
GetWorkspaceGeneralSetting
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to get workspace setting, err: %s"
,
err
))
}
if
workspaceGeneralSetting
.
DisallowSignup
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"sign up is not allowed"
)
}
passwordHash
,
err
:=
bcrypt
.
GenerateFromPassword
([]
byte
(
request
.
Password
),
bcrypt
.
DefaultCost
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to generate password hash, err: %s"
,
err
))
}
create
:=
&
store
.
User
{
Username
:
request
.
Username
,
Nickname
:
request
.
Username
,
PasswordHash
:
string
(
passwordHash
),
}
existingUsers
,
err
:=
s
.
Store
.
ListUsers
(
ctx
,
&
store
.
FindUser
{})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to list users, err: %s"
,
err
))
}
// The first user to sign up is an admin by default.
if
len
(
existingUsers
)
==
0
{
create
.
Role
=
store
.
RoleAdmin
}
else
{
create
.
Role
=
store
.
RoleUser
}
user
,
err
:=
s
.
Store
.
CreateUser
(
ctx
,
create
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to create user, err: %s"
,
err
))
}
if
err
:=
s
.
doSignIn
(
ctx
,
user
,
time
.
Now
()
.
Add
(
auth
.
AccessTokenDuration
));
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
fmt
.
Sprintf
(
"failed to sign in, err: %s"
,
err
))
}
metric
.
Enqueue
(
"user sign up"
)
return
&
apiv2pb
.
SignUpResponse
{
User
:
convertUserFromStore
(
user
),
},
nil
}
func
(
*
APIV2Service
)
SignOut
(
ctx
context
.
Context
,
_
*
apiv2pb
.
SignOutRequest
)
(
*
apiv2pb
.
SignOutResponse
,
error
)
{
if
err
:=
clearAccessTokenCookie
(
ctx
);
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to set grpc header, error: %v"
,
err
)
}
return
&
apiv2pb
.
SignOutResponse
{},
nil
}
func
clearAccessTokenCookie
(
ctx
context
.
Context
)
error
{
func
clearAccessTokenCookie
(
ctx
context
.
Context
)
error
{
if
err
:=
grpc
.
SetHeader
(
ctx
,
metadata
.
New
(
map
[
string
]
string
{
if
err
:=
grpc
.
SetHeader
(
ctx
,
metadata
.
New
(
map
[
string
]
string
{
"Set-Cookie"
:
fmt
.
Sprintf
(
"%s=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=Strict"
,
auth
.
AccessTokenCookieName
),
"Set-Cookie"
:
fmt
.
Sprintf
(
"%s=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=Strict"
,
auth
.
AccessTokenCookieName
),
...
@@ -39,3 +233,19 @@ func clearAccessTokenCookie(ctx context.Context) error {
...
@@ -39,3 +233,19 @@ func clearAccessTokenCookie(ctx context.Context) error {
}
}
return
nil
return
nil
}
}
func
(
s
*
APIV2Service
)
GetWorkspaceGeneralSetting
(
ctx
context
.
Context
)
(
*
storepb
.
WorkspaceGeneralSetting
,
error
)
{
workspaceSetting
,
err
:=
s
.
Store
.
GetWorkspaceSetting
(
ctx
,
&
store
.
FindWorkspaceSetting
{
Name
:
storepb
.
WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL
.
String
(),
})
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to get workspace setting"
)
}
workspaceGeneralSetting
:=
&
storepb
.
WorkspaceGeneralSetting
{}
if
workspaceSetting
!=
nil
{
if
err
:=
proto
.
Unmarshal
([]
byte
(
workspaceSetting
.
Value
),
workspaceGeneralSetting
);
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to unmarshal workspace setting"
)
}
}
return
workspaceGeneralSetting
,
nil
}
proto/api/v2/auth_service.proto
View file @
c5a5f67f
...
@@ -39,6 +39,7 @@ message GetAuthStatusResponse {
...
@@ -39,6 +39,7 @@ message GetAuthStatusResponse {
message
SignInRequest
{
message
SignInRequest
{
string
username
=
1
;
string
username
=
1
;
string
password
=
2
;
string
password
=
2
;
bool
never_expire
=
3
;
}
}
message
SignInResponse
{
message
SignInResponse
{
...
...
proto/gen/api/v2/README.md
View file @
c5a5f67f
...
@@ -823,6 +823,7 @@ Used internally for obfuscating the page token.
...
@@ -823,6 +823,7 @@ Used internally for obfuscating the page token.
| ----- | ---- | ----- | ----------- |
| ----- | ---- | ----- | ----------- |
| username |
[
string
](
#string
)
| | |
| username |
[
string
](
#string
)
| | |
| password |
[
string
](
#string
)
| | |
| password |
[
string
](
#string
)
| | |
| never_expire |
[
bool
](
#bool
)
| | |
...
...
proto/gen/api/v2/auth_service.pb.go
View file @
c5a5f67f
...
@@ -111,8 +111,9 @@ type SignInRequest struct {
...
@@ -111,8 +111,9 @@ type SignInRequest struct {
sizeCache
protoimpl
.
SizeCache
sizeCache
protoimpl
.
SizeCache
unknownFields
protoimpl
.
UnknownFields
unknownFields
protoimpl
.
UnknownFields
Username
string
`protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Username
string
`protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Password
string
`protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
Password
string
`protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
NeverExpire
bool
`protobuf:"varint,3,opt,name=never_expire,json=neverExpire,proto3" json:"never_expire,omitempty"`
}
}
func
(
x
*
SignInRequest
)
Reset
()
{
func
(
x
*
SignInRequest
)
Reset
()
{
...
@@ -161,6 +162,13 @@ func (x *SignInRequest) GetPassword() string {
...
@@ -161,6 +162,13 @@ func (x *SignInRequest) GetPassword() string {
return
""
return
""
}
}
func
(
x
*
SignInRequest
)
GetNeverExpire
()
bool
{
if
x
!=
nil
{
return
x
.
NeverExpire
}
return
false
}
type
SignInResponse
struct
{
type
SignInResponse
struct
{
state
protoimpl
.
MessageState
state
protoimpl
.
MessageState
sizeCache
protoimpl
.
SizeCache
sizeCache
protoimpl
.
SizeCache
...
@@ -510,82 +518,84 @@ var file_api_v2_auth_service_proto_rawDesc = []byte{
...
@@ -510,82 +518,84 @@ var file_api_v2_auth_service_proto_rawDesc = []byte{
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x
47
,
0x0a
,
0x0d
,
0x53
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x
6a
,
0x0a
,
0x0d
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x75
,
0x73
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x75
,
0x73
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x75
,
0x73
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x75
,
0x73
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x64
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x64
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x64
,
0x22
,
0x38
,
0x0a
,
0x0e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x52
,
0x65
,
0x77
,
0x6f
,
0x72
,
0x64
,
0x12
,
0x21
,
0x0a
,
0x0c
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x72
,
0x5f
,
0x65
,
0x78
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x70
,
0x69
,
0x72
,
0x65
,
0x18
,
0x03
,
0x20
,
0x01
,
0x28
,
0x08
,
0x52
,
0x0b
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x72
,
0x45
,
0x78
,
0x70
,
0x69
,
0x72
,
0x65
,
0x22
,
0x38
,
0x0a
,
0x0e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x64
,
0x6e
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x0a
,
0x14
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x12
,
0x15
,
0x0a
,
0x06
,
0x69
,
0x64
,
0x70
,
0x5f
,
0x69
,
0x64
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x05
,
0x69
,
0x64
,
0x70
,
0x49
,
0x64
,
0x12
,
0x12
,
0x0a
,
0x72
,
0x22
,
0x64
,
0x0a
,
0x14
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x04
,
0x63
,
0x6f
,
0x64
,
0x65
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x04
,
0x63
,
0x6f
,
0x64
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x12
,
0x15
,
0x0a
,
0x06
,
0x69
,
0x64
,
0x70
,
0x65
,
0x12
,
0x21
,
0x0a
,
0x0c
,
0x72
,
0x65
,
0x64
,
0x69
,
0x72
,
0x65
,
0x63
,
0x74
,
0x5f
,
0x75
,
0x72
,
0x5f
,
0x69
,
0x64
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x52
,
0x05
,
0x69
,
0x64
,
0x70
,
0x49
,
0x64
,
0x69
,
0x18
,
0x03
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x0b
,
0x72
,
0x65
,
0x64
,
0x69
,
0x72
,
0x65
,
0x63
,
0x12
,
0x12
,
0x0a
,
0x04
,
0x63
,
0x6f
,
0x64
,
0x65
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x04
,
0x74
,
0x55
,
0x72
,
0x69
,
0x22
,
0x3f
,
0x0a
,
0x15
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x63
,
0x6f
,
0x64
,
0x65
,
0x12
,
0x21
,
0x0a
,
0x0c
,
0x72
,
0x65
,
0x64
,
0x69
,
0x72
,
0x65
,
0x63
,
0x74
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x5f
,
0x75
,
0x72
,
0x69
,
0x18
,
0x03
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x0b
,
0x72
,
0x65
,
0x64
,
0x69
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x72
,
0x65
,
0x63
,
0x74
,
0x55
,
0x72
,
0x69
,
0x22
,
0x3f
,
0x0a
,
0x15
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x47
,
0x0a
,
0x0d
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x75
,
0x73
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x75
,
0x73
,
0x65
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x64
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x64
,
0x22
,
0x38
,
0x0a
,
0x0e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x12
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x55
,
0x73
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x10
,
0x0a
,
0x0e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x47
,
0x0a
,
0x0d
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x22
,
0x11
,
0x0a
,
0x0f
,
0x53
,
0x69
,
0x55
,
0x70
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x75
,
0x73
,
0x65
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x32
,
0xa9
,
0x04
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x75
,
0x73
,
0x65
,
0x0a
,
0x0b
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x12
,
0x75
,
0x0a
,
0x72
,
0x6e
,
0x61
,
0x6d
,
0x65
,
0x12
,
0x1a
,
0x0a
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x0d
,
0x47
,
0x65
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x12
,
0x22
,
0x64
,
0x18
,
0x02
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x08
,
0x70
,
0x61
,
0x73
,
0x73
,
0x77
,
0x6f
,
0x72
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x47
,
0x65
,
0x64
,
0x22
,
0x38
,
0x0a
,
0x0e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x26
,
0x0a
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x73
,
0x74
,
0x1a
,
0x23
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x0b
,
0x32
,
0x12
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x32
,
0x2e
,
0x47
,
0x65
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x52
,
0x2e
,
0x55
,
0x73
,
0x65
,
0x72
,
0x52
,
0x04
,
0x75
,
0x73
,
0x65
,
0x72
,
0x22
,
0x10
,
0x0a
,
0x0e
,
0x53
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1b
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x15
,
0x22
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x22
,
0x11
,
0x0a
,
0x13
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x74
,
0x0f
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x61
,
0x74
,
0x75
,
0x73
,
0x12
,
0x60
,
0x0a
,
0x06
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x12
,
0x1b
,
0x32
,
0xa9
,
0x04
,
0x0a
,
0x0b
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x12
,
0x75
,
0x0a
,
0x0d
,
0x47
,
0x65
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x12
,
0x22
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x47
,
0x65
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x23
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x47
,
0x65
,
0x74
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1b
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x15
,
0x22
,
0x13
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x74
,
0x61
,
0x74
,
0x75
,
0x73
,
0x12
,
0x60
,
0x0a
,
0x06
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x12
,
0x1b
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x1c
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x1c
,
0x2e
,
0x6d
,
0x65
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1b
,
0x82
,
0xd3
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0xe4
,
0x93
,
0x02
,
0x15
,
0x22
,
0x13
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x6e
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1b
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x69
,
0x6e
,
0x12
,
0x79
,
0x0a
,
0x0d
,
0x53
,
0x69
,
0x67
,
0x15
,
0x22
,
0x13
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x12
,
0x22
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x69
,
0x6e
,
0x12
,
0x79
,
0x0a
,
0x0d
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x12
,
0x22
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x23
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x23
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1f
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x19
,
0x22
,
0x17
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x69
,
0x6e
,
0x2f
,
0x73
,
0x73
,
0x6f
,
0x12
,
0x60
,
0x0a
,
0x06
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x12
,
0x1b
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x1c
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1b
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x15
,
0x22
,
0x13
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x75
,
0x70
,
0x12
,
0x64
,
0x0a
,
0x07
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x12
,
0x1c
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x1d
,
0x2e
,
0x6d
,
0x67
,
0x6e
,
0x49
,
0x6e
,
0x57
,
0x69
,
0x74
,
0x68
,
0x53
,
0x53
,
0x4f
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1f
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x19
,
0x22
,
0x17
,
0x2f
,
0x61
,
0x70
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1c
,
0x82
,
0xd3
,
0xe4
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x69
,
0x6e
,
0x93
,
0x02
,
0x16
,
0x22
,
0x14
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x2f
,
0x73
,
0x73
,
0x6f
,
0x12
,
0x60
,
0x0a
,
0x06
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x12
,
0x1b
,
0x68
,
0x2f
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x6f
,
0x75
,
0x74
,
0x42
,
0xa8
,
0x01
,
0x0a
,
0x10
,
0x63
,
0x6f
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x6d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x42
,
0x10
,
0x67
,
0x6e
,
0x55
,
0x70
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x1c
,
0x2e
,
0x6d
,
0x65
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x55
,
0x50
,
0x01
,
0x5a
,
0x30
,
0x67
,
0x69
,
0x74
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x70
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1b
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x15
,
0x22
,
0x13
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x67
,
0x65
,
0x6e
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x3b
,
0x61
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x75
,
0x70
,
0x12
,
0x64
,
0x0a
,
0x07
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x70
,
0x69
,
0x76
,
0x32
,
0xa2
,
0x02
,
0x03
,
0x4d
,
0x41
,
0x58
,
0xaa
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x74
,
0x12
,
0x1c
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x6f
,
0x73
,
0x2e
,
0x41
,
0x70
,
0x69
,
0x2e
,
0x56
,
0x32
,
0xca
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x2e
,
0x53
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x71
,
0x75
,
0x65
,
0x73
,
0x74
,
0x1a
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0xe2
,
0x02
,
0x18
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x1d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x2e
,
0x53
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x61
,
0x64
,
0x69
,
0x67
,
0x6e
,
0x4f
,
0x75
,
0x74
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x22
,
0x1c
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0e
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x41
,
0x70
,
0x69
,
0x82
,
0xd3
,
0xe4
,
0x93
,
0x02
,
0x16
,
0x22
,
0x14
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x2f
,
0x3a
,
0x3a
,
0x56
,
0x32
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
0x61
,
0x75
,
0x74
,
0x68
,
0x2f
,
0x73
,
0x69
,
0x67
,
0x6e
,
0x6f
,
0x75
,
0x74
,
0x42
,
0xa8
,
0x01
,
0x0a
,
0x10
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x61
,
0x70
,
0x69
,
0x2e
,
0x76
,
0x32
,
0x42
,
0x10
,
0x41
,
0x75
,
0x74
,
0x68
,
0x53
,
0x65
,
0x72
,
0x76
,
0x69
,
0x63
,
0x65
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x50
,
0x01
,
0x5a
,
0x30
,
0x67
,
0x69
,
0x74
,
0x68
,
0x75
,
0x62
,
0x2e
,
0x63
,
0x6f
,
0x6d
,
0x2f
,
0x75
,
0x73
,
0x65
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x6d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x2f
,
0x67
,
0x65
,
0x6e
,
0x2f
,
0x61
,
0x70
,
0x69
,
0x2f
,
0x76
,
0x32
,
0x3b
,
0x61
,
0x70
,
0x69
,
0x76
,
0x32
,
0xa2
,
0x02
,
0x03
,
0x4d
,
0x41
,
0x58
,
0xaa
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x2e
,
0x41
,
0x70
,
0x69
,
0x2e
,
0x56
,
0x32
,
0xca
,
0x02
,
0x0c
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0xe2
,
0x02
,
0x18
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x5c
,
0x41
,
0x70
,
0x69
,
0x5c
,
0x56
,
0x32
,
0x5c
,
0x47
,
0x50
,
0x42
,
0x4d
,
0x65
,
0x74
,
0x61
,
0x64
,
0x61
,
0x74
,
0x61
,
0xea
,
0x02
,
0x0e
,
0x4d
,
0x65
,
0x6d
,
0x6f
,
0x73
,
0x3a
,
0x3a
,
0x41
,
0x70
,
0x69
,
0x3a
,
0x3a
,
0x56
,
0x32
,
0x62
,
0x06
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x33
,
}
}
var
(
var
(
...
...
web/src/components/UserBanner.tsx
View file @
c5a5f67f
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
classNames
from
"classnames"
;
import
classNames
from
"classnames"
;
import
*
as
api
from
"@/helpers/api
"
;
import
{
authServiceClient
}
from
"@/grpcweb
"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -21,7 +21,7 @@ const UserBanner = (props: Props) => {
...
@@ -21,7 +21,7 @@ const UserBanner = (props: Props) => {
const
avatarUrl
=
user
?
user
.
avatarUrl
:
systemStatus
.
customizedProfile
.
logoUrl
;
const
avatarUrl
=
user
?
user
.
avatarUrl
:
systemStatus
.
customizedProfile
.
logoUrl
;
const
handleSignOut
=
async
()
=>
{
const
handleSignOut
=
async
()
=>
{
await
a
pi
.
signout
(
);
await
a
uthServiceClient
.
signOut
({}
);
window
.
location
.
href
=
"/auth"
;
window
.
location
.
href
=
"/auth"
;
};
};
...
...
web/src/helpers/api.ts
View file @
c5a5f67f
...
@@ -13,33 +13,6 @@ export function upsertSystemSetting(systemSetting: SystemSetting) {
...
@@ -13,33 +13,6 @@ export function upsertSystemSetting(systemSetting: SystemSetting) {
return
axios
.
post
<
SystemSetting
>
(
"/api/v1/system/setting"
,
systemSetting
);
return
axios
.
post
<
SystemSetting
>
(
"/api/v1/system/setting"
,
systemSetting
);
}
}
export
function
signin
(
username
:
string
,
password
:
string
,
remember
:
boolean
)
{
return
axios
.
post
<
User
>
(
"/api/v1/auth/signin"
,
{
username
,
password
,
remember
,
});
}
export
function
signinWithSSO
(
identityProviderId
:
IdentityProviderId
,
code
:
string
,
redirectUri
:
string
)
{
return
axios
.
post
<
User
>
(
"/api/v1/auth/signin/sso"
,
{
identityProviderId
,
code
,
redirectUri
,
});
}
export
function
signup
(
username
:
string
,
password
:
string
)
{
return
axios
.
post
<
User
>
(
"/api/v1/auth/signup"
,
{
username
,
password
,
});
}
export
function
signout
()
{
return
axios
.
post
(
"/api/v1/auth/signout"
);
}
export
function
createResourceWithBlob
(
formData
:
FormData
)
{
export
function
createResourceWithBlob
(
formData
:
FormData
)
{
return
axios
.
post
<
Resource
>
(
"/api/v1/resource/blob"
,
formData
);
return
axios
.
post
<
Resource
>
(
"/api/v1/resource/blob"
,
formData
);
}
}
...
...
web/src/pages/AuthCallback.tsx
View file @
c5a5f67f
...
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
...
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useSearchParams
}
from
"react-router-dom"
;
import
{
useSearchParams
}
from
"react-router-dom"
;
import
Icon
from
"@/components/Icon"
;
import
Icon
from
"@/components/Icon"
;
import
*
as
api
from
"@/helpers/api
"
;
import
{
authServiceClient
}
from
"@/grpcweb
"
;
import
{
absolutifyLink
}
from
"@/helpers/utils"
;
import
{
absolutifyLink
}
from
"@/helpers/utils"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
useUserStore
}
from
"@/store/v1"
;
import
{
useUserStore
}
from
"@/store/v1"
;
...
@@ -32,9 +32,13 @@ const AuthCallback = () => {
...
@@ -32,9 +32,13 @@ const AuthCallback = () => {
const
redirectUri
=
absolutifyLink
(
"/auth/callback"
);
const
redirectUri
=
absolutifyLink
(
"/auth/callback"
);
const
identityProviderId
=
Number
(
last
(
state
.
split
(
"-"
)));
const
identityProviderId
=
Number
(
last
(
state
.
split
(
"-"
)));
if
(
identityProviderId
)
{
if
(
identityProviderId
)
{
api
authServiceClient
.
signinWithSSO
(
identityProviderId
,
code
,
redirectUri
)
.
signInWithSSO
({
.
then
(
async
({
data
:
user
})
=>
{
idpId
:
identityProviderId
,
code
,
redirectUri
,
})
.
then
(
async
({
user
})
=>
{
setState
({
setState
({
loading
:
false
,
loading
:
false
,
errorMessage
:
""
,
errorMessage
:
""
,
...
...
web/src/pages/SignIn.tsx
View file @
c5a5f67f
...
@@ -4,6 +4,7 @@ import { toast } from "react-hot-toast";
...
@@ -4,6 +4,7 @@ import { toast } from "react-hot-toast";
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
import
AppearanceSelect
from
"@/components/AppearanceSelect"
;
import
AppearanceSelect
from
"@/components/AppearanceSelect"
;
import
LocaleSelect
from
"@/components/LocaleSelect"
;
import
LocaleSelect
from
"@/components/LocaleSelect"
;
import
{
authServiceClient
}
from
"@/grpcweb"
;
import
*
as
api
from
"@/helpers/api"
;
import
*
as
api
from
"@/helpers/api"
;
import
{
absolutifyLink
}
from
"@/helpers/utils"
;
import
{
absolutifyLink
}
from
"@/helpers/utils"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
...
@@ -75,7 +76,7 @@ const SignIn = () => {
...
@@ -75,7 +76,7 @@ const SignIn = () => {
try
{
try
{
actionBtnLoadingState
.
setLoading
();
actionBtnLoadingState
.
setLoading
();
const
{
data
:
user
}
=
await
api
.
signin
(
username
,
password
,
remember
);
const
{
user
}
=
await
authServiceClient
.
signIn
({
username
,
password
,
neverExpire
:
remember
}
);
if
(
user
)
{
if
(
user
)
{
await
userStore
.
fetchCurrentUser
();
await
userStore
.
fetchCurrentUser
();
navigateTo
(
"/"
);
navigateTo
(
"/"
);
...
...
web/src/pages/SignUp.tsx
View file @
c5a5f67f
...
@@ -4,7 +4,7 @@ import { toast } from "react-hot-toast";
...
@@ -4,7 +4,7 @@ import { toast } from "react-hot-toast";
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
import
AppearanceSelect
from
"@/components/AppearanceSelect"
;
import
AppearanceSelect
from
"@/components/AppearanceSelect"
;
import
LocaleSelect
from
"@/components/LocaleSelect"
;
import
LocaleSelect
from
"@/components/LocaleSelect"
;
import
*
as
api
from
"@/helpers/api
"
;
import
{
authServiceClient
}
from
"@/grpcweb
"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
...
@@ -55,7 +55,7 @@ const SignUp = () => {
...
@@ -55,7 +55,7 @@ const SignUp = () => {
try
{
try
{
actionBtnLoadingState
.
setLoading
();
actionBtnLoadingState
.
setLoading
();
const
{
data
:
user
}
=
await
api
.
signup
(
username
,
password
);
const
{
user
}
=
await
authServiceClient
.
signUp
({
username
,
password
}
);
if
(
user
)
{
if
(
user
)
{
await
userStore
.
fetchCurrentUser
();
await
userStore
.
fetchCurrentUser
();
navigateTo
(
"/"
);
navigateTo
(
"/"
);
...
...
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