mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
refactor: migrate auth service
This commit is contained in:
@ -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,
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
|||||||
}, 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 {
|
|||||||
}
|
}
|
||||||
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
|
||||||
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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) | | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 {
|
|||||||
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{
|
|||||||
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, 0x47, 0x0a, 0x0d, 0x53,
|
0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x6a, 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,
|
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69,
|
||||||
0x68, 0x53, 0x53, 0x4f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65,
|
0x67, 0x6e, 0x49, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x53, 0x53, 0x4f, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49,
|
0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x61, 0x70,
|
||||||
0x6e, 0x57, 0x69, 0x74, 0x68, 0x53, 0x53, 0x4f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e,
|
||||||
0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76,
|
0x2f, 0x73, 0x73, 0x6f, 0x12, 0x60, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x12, 0x1b,
|
||||||
0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x2f, 0x73, 0x73,
|
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69,
|
||||||
0x6f, 0x12, 0x60, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x12, 0x1b, 0x2e, 0x6d, 0x65,
|
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,
|
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,
|
0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x52, 0x65,
|
0x15, 0x22, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f,
|
||||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x22, 0x13,
|
0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75,
|
||||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67,
|
0x74, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||||
0x6e, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x12, 0x1c,
|
0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||||
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69,
|
0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53,
|
||||||
0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d,
|
0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c,
|
||||||
0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e,
|
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f,
|
||||||
0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4,
|
0x61, 0x75, 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x6f, 0x75, 0x74, 0x42, 0xa8, 0x01, 0x0a,
|
||||||
0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74,
|
0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||||
0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x6f, 0x75, 0x74, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f,
|
0x32, 0x42, 0x10, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72,
|
||||||
0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10,
|
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||||
0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f,
|
0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
|
||||||
0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75,
|
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76,
|
||||||
0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72,
|
0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c,
|
||||||
0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61,
|
0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d,
|
||||||
0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d,
|
0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65,
|
||||||
0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f,
|
0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
|
||||||
0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
|
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a,
|
||||||
0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64,
|
0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
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 (
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
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) => {
|
|||||||
const avatarUrl = user ? user.avatarUrl : systemStatus.customizedProfile.logoUrl;
|
const avatarUrl = user ? user.avatarUrl : systemStatus.customizedProfile.logoUrl;
|
||||||
|
|
||||||
const handleSignOut = async () => {
|
const handleSignOut = async () => {
|
||||||
await api.signout();
|
await authServiceClient.signOut({});
|
||||||
window.location.href = "/auth";
|
window.location.href = "/auth";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 = () => {
|
|||||||
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: "",
|
||||||
|
@ -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 = () => {
|
|||||||
|
|
||||||
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("/");
|
||||||
|
@ -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 = () => {
|
|||||||
|
|
||||||
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("/");
|
||||||
|
Reference in New Issue
Block a user