mirror of https://github.com/usememos/memos.git
chore: update auth service
This commit is contained in:
parent
59eae4465a
commit
5821bb7a65
|
|
@ -30,15 +30,6 @@ service AuthService {
|
|||
rpc DeleteSession(DeleteSessionRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {delete: "/api/v1/auth/sessions/current"};
|
||||
}
|
||||
|
||||
// SignUp creates a new user account with username and password.
|
||||
// Returns the newly created user information upon successful registration.
|
||||
rpc SignUp(SignUpRequest) returns (User) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/auth/signup"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message GetCurrentSessionRequest {}
|
||||
|
|
@ -88,13 +79,3 @@ message SSOCredentials {
|
|||
}
|
||||
|
||||
message DeleteSessionRequest {}
|
||||
|
||||
message SignUpRequest {
|
||||
// The username to sign up with.
|
||||
// Required field that must be unique across the system.
|
||||
string username = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
|
||||
// The password to sign up with.
|
||||
// Required field that should meet security requirements.
|
||||
string password = 2 [(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,62 +358,6 @@ func (*DeleteSessionRequest) Descriptor() ([]byte, []int) {
|
|||
return file_api_v1_auth_service_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
type SignUpRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The username to sign up with.
|
||||
// Required field that must be unique across the system.
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||
// The password to sign up with.
|
||||
// Required field that should meet security requirements.
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SignUpRequest) Reset() {
|
||||
*x = SignUpRequest{}
|
||||
mi := &file_api_v1_auth_service_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SignUpRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SignUpRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SignUpRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v1_auth_service_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SignUpRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SignUpRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v1_auth_service_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *SignUpRequest) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SignUpRequest) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_api_v1_auth_service_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_api_v1_auth_service_proto_rawDesc = "" +
|
||||
|
|
@ -434,15 +378,11 @@ const file_api_v1_auth_service_proto_rawDesc = "" +
|
|||
"\x06idp_id\x18\x01 \x01(\x05B\x03\xe0A\x02R\x05idpId\x12\x17\n" +
|
||||
"\x04code\x18\x02 \x01(\tB\x03\xe0A\x02R\x04code\x12&\n" +
|
||||
"\fredirect_uri\x18\x03 \x01(\tB\x03\xe0A\x02R\vredirectUri\"\x16\n" +
|
||||
"\x14DeleteSessionRequest\"Q\n" +
|
||||
"\rSignUpRequest\x12\x1f\n" +
|
||||
"\busername\x18\x01 \x01(\tB\x03\xe0A\x02R\busername\x12\x1f\n" +
|
||||
"\bpassword\x18\x02 \x01(\tB\x03\xe0A\x02R\bpassword2\xbf\x03\n" +
|
||||
"\x14DeleteSessionRequest2\xe4\x02\n" +
|
||||
"\vAuthService\x12v\n" +
|
||||
"\x11GetCurrentSession\x12&.memos.api.v1.GetCurrentSessionRequest\x1a\x12.memos.api.v1.User\"%\x82\xd3\xe4\x93\x02\x1f\x12\x1d/api/v1/auth/sessions/current\x12i\n" +
|
||||
"\rCreateSession\x12\".memos.api.v1.CreateSessionRequest\x1a\x12.memos.api.v1.User\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/api/v1/auth/sessions\x12r\n" +
|
||||
"\rDeleteSession\x12\".memos.api.v1.DeleteSessionRequest\x1a\x16.google.protobuf.Empty\"%\x82\xd3\xe4\x93\x02\x1f*\x1d/api/v1/auth/sessions/current\x12Y\n" +
|
||||
"\x06SignUp\x12\x1b.memos.api.v1.SignUpRequest\x1a\x12.memos.api.v1.User\"\x1e\x82\xd3\xe4\x93\x02\x18:\x01*\"\x13/api/v1/auth/signupB\xa8\x01\n" +
|
||||
"\rDeleteSession\x12\".memos.api.v1.DeleteSessionRequest\x1a\x16.google.protobuf.Empty\"%\x82\xd3\xe4\x93\x02\x1f*\x1d/api/v1/auth/sessions/currentB\xa8\x01\n" +
|
||||
"\x10com.memos.api.v1B\x10AuthServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
|
||||
|
||||
var (
|
||||
|
|
@ -457,7 +397,7 @@ func file_api_v1_auth_service_proto_rawDescGZIP() []byte {
|
|||
return file_api_v1_auth_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_api_v1_auth_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_api_v1_auth_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_api_v1_auth_service_proto_goTypes = []any{
|
||||
(*GetCurrentSessionRequest)(nil), // 0: memos.api.v1.GetCurrentSessionRequest
|
||||
(*GetCurrentSessionResponse)(nil), // 1: memos.api.v1.GetCurrentSessionResponse
|
||||
|
|
@ -465,24 +405,21 @@ var file_api_v1_auth_service_proto_goTypes = []any{
|
|||
(*PasswordCredentials)(nil), // 3: memos.api.v1.PasswordCredentials
|
||||
(*SSOCredentials)(nil), // 4: memos.api.v1.SSOCredentials
|
||||
(*DeleteSessionRequest)(nil), // 5: memos.api.v1.DeleteSessionRequest
|
||||
(*SignUpRequest)(nil), // 6: memos.api.v1.SignUpRequest
|
||||
(*User)(nil), // 7: memos.api.v1.User
|
||||
(*emptypb.Empty)(nil), // 8: google.protobuf.Empty
|
||||
(*User)(nil), // 6: memos.api.v1.User
|
||||
(*emptypb.Empty)(nil), // 7: google.protobuf.Empty
|
||||
}
|
||||
var file_api_v1_auth_service_proto_depIdxs = []int32{
|
||||
7, // 0: memos.api.v1.GetCurrentSessionResponse.user:type_name -> memos.api.v1.User
|
||||
6, // 0: memos.api.v1.GetCurrentSessionResponse.user:type_name -> memos.api.v1.User
|
||||
3, // 1: memos.api.v1.CreateSessionRequest.password_credentials:type_name -> memos.api.v1.PasswordCredentials
|
||||
4, // 2: memos.api.v1.CreateSessionRequest.sso_credentials:type_name -> memos.api.v1.SSOCredentials
|
||||
0, // 3: memos.api.v1.AuthService.GetCurrentSession:input_type -> memos.api.v1.GetCurrentSessionRequest
|
||||
2, // 4: memos.api.v1.AuthService.CreateSession:input_type -> memos.api.v1.CreateSessionRequest
|
||||
5, // 5: memos.api.v1.AuthService.DeleteSession:input_type -> memos.api.v1.DeleteSessionRequest
|
||||
6, // 6: memos.api.v1.AuthService.SignUp:input_type -> memos.api.v1.SignUpRequest
|
||||
7, // 7: memos.api.v1.AuthService.GetCurrentSession:output_type -> memos.api.v1.User
|
||||
7, // 8: memos.api.v1.AuthService.CreateSession:output_type -> memos.api.v1.User
|
||||
8, // 9: memos.api.v1.AuthService.DeleteSession:output_type -> google.protobuf.Empty
|
||||
7, // 10: memos.api.v1.AuthService.SignUp:output_type -> memos.api.v1.User
|
||||
7, // [7:11] is the sub-list for method output_type
|
||||
3, // [3:7] is the sub-list for method input_type
|
||||
6, // 6: memos.api.v1.AuthService.GetCurrentSession:output_type -> memos.api.v1.User
|
||||
6, // 7: memos.api.v1.AuthService.CreateSession:output_type -> memos.api.v1.User
|
||||
7, // 8: memos.api.v1.AuthService.DeleteSession:output_type -> google.protobuf.Empty
|
||||
6, // [6:9] is the sub-list for method output_type
|
||||
3, // [3:6] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
|
|
@ -504,7 +441,7 @@ func file_api_v1_auth_service_proto_init() {
|
|||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_v1_auth_service_proto_rawDesc), len(file_api_v1_auth_service_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 7,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -104,33 +104,6 @@ func local_request_AuthService_DeleteSession_0(ctx context.Context, marshaler ru
|
|||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_AuthService_SignUp_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq SignUpRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if req.Body != nil {
|
||||
_, _ = io.Copy(io.Discard, req.Body)
|
||||
}
|
||||
msg, err := client.SignUp(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_AuthService_SignUp_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq SignUpRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := server.SignUp(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
// RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux".
|
||||
// UnaryRPC :call AuthServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
|
|
@ -197,26 +170,6 @@ func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
|||
}
|
||||
forward_AuthService_DeleteSession_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_AuthService_SignUp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.AuthService/SignUp", runtime.WithHTTPPathPattern("/api/v1/auth/signup"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_AuthService_SignUp_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_AuthService_SignUp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -308,23 +261,6 @@ func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
|||
}
|
||||
forward_AuthService_DeleteSession_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_AuthService_SignUp_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)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.AuthService/SignUp", runtime.WithHTTPPathPattern("/api/v1/auth/signup"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AuthService_SignUp_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_AuthService_SignUp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -332,12 +268,10 @@ var (
|
|||
pattern_AuthService_GetCurrentSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "auth", "sessions", "current"}, ""))
|
||||
pattern_AuthService_CreateSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "sessions"}, ""))
|
||||
pattern_AuthService_DeleteSession_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "auth", "sessions", "current"}, ""))
|
||||
pattern_AuthService_SignUp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "signup"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_AuthService_GetCurrentSession_0 = runtime.ForwardResponseMessage
|
||||
forward_AuthService_CreateSession_0 = runtime.ForwardResponseMessage
|
||||
forward_AuthService_DeleteSession_0 = runtime.ForwardResponseMessage
|
||||
forward_AuthService_SignUp_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ const (
|
|||
AuthService_GetCurrentSession_FullMethodName = "/memos.api.v1.AuthService/GetCurrentSession"
|
||||
AuthService_CreateSession_FullMethodName = "/memos.api.v1.AuthService/CreateSession"
|
||||
AuthService_DeleteSession_FullMethodName = "/memos.api.v1.AuthService/DeleteSession"
|
||||
AuthService_SignUp_FullMethodName = "/memos.api.v1.AuthService/SignUp"
|
||||
)
|
||||
|
||||
// AuthServiceClient is the client API for AuthService service.
|
||||
|
|
@ -39,9 +38,6 @@ type AuthServiceClient interface {
|
|||
// DeleteSession terminates the current user session.
|
||||
// This is an idempotent operation that invalidates the user's authentication.
|
||||
DeleteSession(ctx context.Context, in *DeleteSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
// SignUp creates a new user account with username and password.
|
||||
// Returns the newly created user information upon successful registration.
|
||||
SignUp(ctx context.Context, in *SignUpRequest, opts ...grpc.CallOption) (*User, error)
|
||||
}
|
||||
|
||||
type authServiceClient struct {
|
||||
|
|
@ -82,16 +78,6 @@ func (c *authServiceClient) DeleteSession(ctx context.Context, in *DeleteSession
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authServiceClient) SignUp(ctx context.Context, in *SignUpRequest, opts ...grpc.CallOption) (*User, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, AuthService_SignUp_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuthServiceServer is the server API for AuthService service.
|
||||
// All implementations must embed UnimplementedAuthServiceServer
|
||||
// for forward compatibility.
|
||||
|
|
@ -105,9 +91,6 @@ type AuthServiceServer interface {
|
|||
// DeleteSession terminates the current user session.
|
||||
// This is an idempotent operation that invalidates the user's authentication.
|
||||
DeleteSession(context.Context, *DeleteSessionRequest) (*emptypb.Empty, error)
|
||||
// SignUp creates a new user account with username and password.
|
||||
// Returns the newly created user information upon successful registration.
|
||||
SignUp(context.Context, *SignUpRequest) (*User, error)
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
|
|
@ -127,9 +110,6 @@ func (UnimplementedAuthServiceServer) CreateSession(context.Context, *CreateSess
|
|||
func (UnimplementedAuthServiceServer) DeleteSession(context.Context, *DeleteSessionRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteSession not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) SignUp(context.Context, *SignUpRequest) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SignUp not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {}
|
||||
func (UnimplementedAuthServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
|
|
@ -205,24 +185,6 @@ func _AuthService_DeleteSession_Handler(srv interface{}, ctx context.Context, de
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthService_SignUp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SignUpRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).SignUp(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_SignUp_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).SignUp(ctx, req.(*SignUpRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
|
|
@ -242,10 +204,6 @@ var AuthService_ServiceDesc = grpc.ServiceDesc{
|
|||
MethodName: "DeleteSession",
|
||||
Handler: _AuthService_DeleteSession_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SignUp",
|
||||
Handler: _AuthService_SignUp_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v1/auth_service.proto",
|
||||
|
|
|
|||
|
|
@ -188,29 +188,6 @@ paths:
|
|||
$ref: '#/definitions/googlerpcStatus'
|
||||
tags:
|
||||
- AuthService
|
||||
/api/v1/auth/signup:
|
||||
post:
|
||||
summary: |-
|
||||
SignUp creates a new user account with username and password.
|
||||
Returns the newly created user information upon successful registration.
|
||||
operationId: AuthService_SignUp
|
||||
responses:
|
||||
"200":
|
||||
description: A successful response.
|
||||
schema:
|
||||
$ref: '#/definitions/v1User'
|
||||
default:
|
||||
description: An unexpected error response.
|
||||
schema:
|
||||
$ref: '#/definitions/googlerpcStatus'
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/v1SignUpRequest'
|
||||
tags:
|
||||
- AuthService
|
||||
/api/v1/identityProviders:
|
||||
get:
|
||||
summary: ListIdentityProviders lists identity providers.
|
||||
|
|
@ -4097,22 +4074,6 @@ definitions:
|
|||
type: integer
|
||||
format: int32
|
||||
description: The total count of matching users.
|
||||
v1SignUpRequest:
|
||||
type: object
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: |-
|
||||
The username to sign up with.
|
||||
Required field that must be unique across the system.
|
||||
password:
|
||||
type: string
|
||||
description: |-
|
||||
The password to sign up with.
|
||||
Required field that should meet security requirements.
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
v1SpoilerNode:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ var authenticationAllowlistMethods = map[string]bool{
|
|||
"/memos.api.v1.IdentityProviderService/ListIdentityProviders": true,
|
||||
"/memos.api.v1.AuthService/CreateSession": true,
|
||||
"/memos.api.v1.AuthService/GetCurrentSession": true,
|
||||
"/memos.api.v1.AuthService/SignUp": true,
|
||||
"/memos.api.v1.UserService/CreateUser": true,
|
||||
"/memos.api.v1.UserService/GetUser": true,
|
||||
"/memos.api.v1.UserService/GetUserAvatar": true,
|
||||
"/memos.api.v1.UserService/GetUserStats": true,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import (
|
|||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/usememos/memos/internal/base"
|
||||
"github.com/usememos/memos/internal/util"
|
||||
"github.com/usememos/memos/plugin/idp"
|
||||
"github.com/usememos/memos/plugin/idp/oauth2"
|
||||
|
|
@ -206,54 +205,6 @@ func (s *APIV1Service) doSignIn(ctx context.Context, user *store.User, expireTim
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *APIV1Service) SignUp(ctx context.Context, request *v1pb.SignUpRequest) (*v1pb.User, error) {
|
||||
workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get workspace general setting, error: %v", err)
|
||||
}
|
||||
if workspaceGeneralSetting.DisallowUserRegistration {
|
||||
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, "failed to generate password hash, error: %v", err)
|
||||
}
|
||||
|
||||
create := &store.User{
|
||||
Username: request.Username,
|
||||
Nickname: request.Username,
|
||||
PasswordHash: string(passwordHash),
|
||||
}
|
||||
if !base.UIDMatcher.MatchString(strings.ToLower(create.Username)) {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", create.Username)
|
||||
}
|
||||
|
||||
hostUserType := store.RoleHost
|
||||
existedHostUsers, err := s.Store.ListUsers(ctx, &store.FindUser{
|
||||
Role: &hostUserType,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list host users, error: %v", err)
|
||||
}
|
||||
if len(existedHostUsers) == 0 {
|
||||
// Change the default role to host if there is no host user.
|
||||
create.Role = store.RoleHost
|
||||
} else {
|
||||
create.Role = store.RoleUser
|
||||
}
|
||||
|
||||
user, err := s.Store.CreateUser(ctx, create)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to create user, error: %v", err)
|
||||
}
|
||||
|
||||
if err := s.doSignIn(ctx, user, time.Now().Add(AccessTokenDuration)); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to sign in, error: %v", err)
|
||||
}
|
||||
return convertUserFromStore(user), nil
|
||||
}
|
||||
|
||||
func (s *APIV1Service) DeleteSession(ctx context.Context, _ *v1pb.DeleteSessionRequest) (*emptypb.Empty, error) {
|
||||
user, err := s.GetCurrentUser(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -144,15 +144,36 @@ func (s *APIV1Service) GetUserAvatar(ctx context.Context, request *v1pb.GetUserA
|
|||
}
|
||||
|
||||
func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserRequest) (*v1pb.User, error) {
|
||||
currentUser, err := s.GetCurrentUser(ctx)
|
||||
// Check if there are any existing host users (for first-time setup detection)
|
||||
hostUserType := store.RoleHost
|
||||
existedHostUsers, err := s.Store.ListUsers(ctx, &store.FindUser{
|
||||
Role: &hostUserType,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "failed to list host users: %v", err)
|
||||
}
|
||||
if currentUser.Role != store.RoleHost {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
|
||||
|
||||
// Determine the role to assign and check permissions
|
||||
var roleToAssign store.Role
|
||||
if len(existedHostUsers) == 0 {
|
||||
// First-time setup: create the first user as HOST (no authentication required)
|
||||
roleToAssign = store.RoleHost
|
||||
} else {
|
||||
// Regular user creation: allow unauthenticated creation of normal users
|
||||
// But if authenticated, check if user has HOST permission for any role
|
||||
currentUser, err := s.GetCurrentUser(ctx)
|
||||
if err == nil && currentUser != nil && currentUser.Role == store.RoleHost {
|
||||
// Authenticated HOST user can create users with any role specified in request
|
||||
if request.User.Role != v1pb.User_ROLE_UNSPECIFIED {
|
||||
roleToAssign = convertUserRoleToStore(request.User.Role)
|
||||
} else {
|
||||
roleToAssign = store.RoleUser
|
||||
}
|
||||
} else {
|
||||
// Unauthenticated or non-HOST users can only create normal users
|
||||
roleToAssign = store.RoleUser
|
||||
}
|
||||
}
|
||||
// TODO: Handle request_id for idempotency
|
||||
// TODO: Handle user_id field if provided
|
||||
|
||||
if !base.UIDMatcher.MatchString(strings.ToLower(request.User.Username)) {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username)
|
||||
|
|
@ -165,7 +186,7 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
|
|||
Username: request.User.Username,
|
||||
Email: request.User.Email,
|
||||
DisplayName: request.User.DisplayName,
|
||||
Role: request.User.Role,
|
||||
Role: convertUserRoleFromStore(roleToAssign),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +197,7 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
|
|||
|
||||
user, err := s.Store.CreateUser(ctx, &store.User{
|
||||
Username: request.User.Username,
|
||||
Role: convertUserRoleToStore(request.User.Role),
|
||||
Role: roleToAssign,
|
||||
Email: request.User.Email,
|
||||
Nickname: request.User.DisplayName,
|
||||
PasswordHash: string(passwordHash),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@ import { useState } from "react";
|
|||
import { toast } from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
import AuthFooter from "@/components/AuthFooter";
|
||||
import { authServiceClient } from "@/grpcweb";
|
||||
import { authServiceClient, userServiceClient } from "@/grpcweb";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { workspaceStore } from "@/store/v2";
|
||||
import { initialUserStore } from "@/store/v2/user";
|
||||
import { User, User_Role } from "@/types/proto/api/v1/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
const SignUp = observer(() => {
|
||||
|
|
@ -47,7 +48,15 @@ const SignUp = observer(() => {
|
|||
|
||||
try {
|
||||
actionBtnLoadingState.setLoading();
|
||||
await authServiceClient.signUp({ username, password });
|
||||
const user = User.fromPartial({
|
||||
username,
|
||||
password,
|
||||
role: User_Role.USER,
|
||||
});
|
||||
await userServiceClient.createUser({ user });
|
||||
await authServiceClient.createSession({
|
||||
passwordCredentials: { username, password },
|
||||
});
|
||||
await initialUserStore();
|
||||
navigateTo("/");
|
||||
} catch (error: any) {
|
||||
|
|
|
|||
|
|
@ -68,19 +68,6 @@ export interface SSOCredentials {
|
|||
export interface DeleteSessionRequest {
|
||||
}
|
||||
|
||||
export interface SignUpRequest {
|
||||
/**
|
||||
* The username to sign up with.
|
||||
* Required field that must be unique across the system.
|
||||
*/
|
||||
username: string;
|
||||
/**
|
||||
* The password to sign up with.
|
||||
* Required field that should meet security requirements.
|
||||
*/
|
||||
password: string;
|
||||
}
|
||||
|
||||
function createBaseGetCurrentSessionRequest(): GetCurrentSessionRequest {
|
||||
return {};
|
||||
}
|
||||
|
|
@ -397,64 +384,6 @@ export const DeleteSessionRequest: MessageFns<DeleteSessionRequest> = {
|
|||
},
|
||||
};
|
||||
|
||||
function createBaseSignUpRequest(): SignUpRequest {
|
||||
return { username: "", password: "" };
|
||||
}
|
||||
|
||||
export const SignUpRequest: MessageFns<SignUpRequest> = {
|
||||
encode(message: SignUpRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.username !== "") {
|
||||
writer.uint32(10).string(message.username);
|
||||
}
|
||||
if (message.password !== "") {
|
||||
writer.uint32(18).string(message.password);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
decode(input: BinaryReader | Uint8Array, length?: number): SignUpRequest {
|
||||
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
||||
let end = length === undefined ? reader.len : reader.pos + length;
|
||||
const message = createBaseSignUpRequest();
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.username = reader.string();
|
||||
continue;
|
||||
}
|
||||
case 2: {
|
||||
if (tag !== 18) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.password = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
}
|
||||
reader.skip(tag & 7);
|
||||
}
|
||||
return message;
|
||||
},
|
||||
|
||||
create(base?: DeepPartial<SignUpRequest>): SignUpRequest {
|
||||
return SignUpRequest.fromPartial(base ?? {});
|
||||
},
|
||||
fromPartial(object: DeepPartial<SignUpRequest>): SignUpRequest {
|
||||
const message = createBaseSignUpRequest();
|
||||
message.username = object.username ?? "";
|
||||
message.password = object.password ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
export type AuthServiceDefinition = typeof AuthServiceDefinition;
|
||||
export const AuthServiceDefinition = {
|
||||
name: "AuthService",
|
||||
|
|
@ -608,50 +537,6 @@ export const AuthServiceDefinition = {
|
|||
},
|
||||
},
|
||||
},
|
||||
/**
|
||||
* SignUp creates a new user account with username and password.
|
||||
* Returns the newly created user information upon successful registration.
|
||||
*/
|
||||
signUp: {
|
||||
name: "SignUp",
|
||||
requestType: SignUpRequest,
|
||||
requestStream: false,
|
||||
responseType: User,
|
||||
responseStream: false,
|
||||
options: {
|
||||
_unknownFields: {
|
||||
578365826: [
|
||||
new Uint8Array([
|
||||
24,
|
||||
58,
|
||||
1,
|
||||
42,
|
||||
34,
|
||||
19,
|
||||
47,
|
||||
97,
|
||||
112,
|
||||
105,
|
||||
47,
|
||||
118,
|
||||
49,
|
||||
47,
|
||||
97,
|
||||
117,
|
||||
116,
|
||||
104,
|
||||
47,
|
||||
115,
|
||||
105,
|
||||
103,
|
||||
110,
|
||||
117,
|
||||
112,
|
||||
]),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue