diff --git a/Makefile b/Makefile index b90223f8..f3baad1d 100644 --- a/Makefile +++ b/Makefile @@ -58,8 +58,8 @@ install: install-daemon install-cli .PHONY: proto proto: go build -o build/protoc-gen-go google.golang.org/protobuf/cmd/protoc-gen-go - protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative api/protos/auth.proto - protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative api/protos/subscription.proto + protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative account/protos/auth.proto + protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative account/protos/subscription.proto protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative issue/issue.proto .PHONY: test diff --git a/account/protos/auth.pb.go b/account/protos/auth.pb.go index 49b7cd78..8b349854 100644 --- a/account/protos/auth.pb.go +++ b/account/protos/auth.pb.go @@ -2,7 +2,7 @@ // versions: // protoc-gen-go v1.36.11 // protoc v5.28.3 -// source: api/protos/auth.proto +// source: account/protos/auth.proto package protos @@ -38,7 +38,7 @@ type SignupRequest struct { func (x *SignupRequest) Reset() { *x = SignupRequest{} - mi := &file_api_protos_auth_proto_msgTypes[0] + mi := &file_account_protos_auth_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -50,7 +50,7 @@ func (x *SignupRequest) String() string { func (*SignupRequest) ProtoMessage() {} func (x *SignupRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[0] + mi := &file_account_protos_auth_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -63,7 +63,7 @@ func (x *SignupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignupRequest.ProtoReflect.Descriptor instead. func (*SignupRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{0} + return file_account_protos_auth_proto_rawDescGZIP(), []int{0} } func (x *SignupRequest) GetEmail() string { @@ -113,7 +113,7 @@ type SignupResponse struct { func (x *SignupResponse) Reset() { *x = SignupResponse{} - mi := &file_api_protos_auth_proto_msgTypes[1] + mi := &file_account_protos_auth_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -125,7 +125,7 @@ func (x *SignupResponse) String() string { func (*SignupResponse) ProtoMessage() {} func (x *SignupResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[1] + mi := &file_account_protos_auth_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -138,7 +138,7 @@ func (x *SignupResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignupResponse.ProtoReflect.Descriptor instead. func (*SignupResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{1} + return file_account_protos_auth_proto_rawDescGZIP(), []int{1} } func (x *SignupResponse) GetId() string { @@ -177,7 +177,7 @@ type EmptyResponse struct { func (x *EmptyResponse) Reset() { *x = EmptyResponse{} - mi := &file_api_protos_auth_proto_msgTypes[2] + mi := &file_account_protos_auth_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -189,7 +189,7 @@ func (x *EmptyResponse) String() string { func (*EmptyResponse) ProtoMessage() {} func (x *EmptyResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[2] + mi := &file_account_protos_auth_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -202,7 +202,7 @@ func (x *EmptyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EmptyResponse.ProtoReflect.Descriptor instead. func (*EmptyResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{2} + return file_account_protos_auth_proto_rawDescGZIP(), []int{2} } // POST /users/signup/resend/email @@ -216,7 +216,7 @@ type SignupEmailResendRequest struct { func (x *SignupEmailResendRequest) Reset() { *x = SignupEmailResendRequest{} - mi := &file_api_protos_auth_proto_msgTypes[3] + mi := &file_account_protos_auth_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -228,7 +228,7 @@ func (x *SignupEmailResendRequest) String() string { func (*SignupEmailResendRequest) ProtoMessage() {} func (x *SignupEmailResendRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[3] + mi := &file_account_protos_auth_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -241,7 +241,7 @@ func (x *SignupEmailResendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignupEmailResendRequest.ProtoReflect.Descriptor instead. func (*SignupEmailResendRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{3} + return file_account_protos_auth_proto_rawDescGZIP(), []int{3} } func (x *SignupEmailResendRequest) GetEmail() string { @@ -269,7 +269,7 @@ type ConfirmSignupRequest struct { func (x *ConfirmSignupRequest) Reset() { *x = ConfirmSignupRequest{} - mi := &file_api_protos_auth_proto_msgTypes[4] + mi := &file_account_protos_auth_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -281,7 +281,7 @@ func (x *ConfirmSignupRequest) String() string { func (*ConfirmSignupRequest) ProtoMessage() {} func (x *ConfirmSignupRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[4] + mi := &file_account_protos_auth_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -294,7 +294,7 @@ func (x *ConfirmSignupRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfirmSignupRequest.ProtoReflect.Descriptor instead. func (*ConfirmSignupRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{4} + return file_account_protos_auth_proto_rawDescGZIP(), []int{4} } func (x *ConfirmSignupRequest) GetEmail() string { @@ -321,7 +321,7 @@ type GetSaltResponse struct { func (x *GetSaltResponse) Reset() { *x = GetSaltResponse{} - mi := &file_api_protos_auth_proto_msgTypes[5] + mi := &file_account_protos_auth_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -333,7 +333,7 @@ func (x *GetSaltResponse) String() string { func (*GetSaltResponse) ProtoMessage() {} func (x *GetSaltResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[5] + mi := &file_account_protos_auth_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -346,7 +346,7 @@ func (x *GetSaltResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSaltResponse.ProtoReflect.Descriptor instead. func (*GetSaltResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{5} + return file_account_protos_auth_proto_rawDescGZIP(), []int{5} } func (x *GetSaltResponse) GetSalt() []byte { @@ -367,7 +367,7 @@ type PrepareRequest struct { func (x *PrepareRequest) Reset() { *x = PrepareRequest{} - mi := &file_api_protos_auth_proto_msgTypes[6] + mi := &file_account_protos_auth_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -379,7 +379,7 @@ func (x *PrepareRequest) String() string { func (*PrepareRequest) ProtoMessage() {} func (x *PrepareRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[6] + mi := &file_account_protos_auth_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -392,7 +392,7 @@ func (x *PrepareRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareRequest.ProtoReflect.Descriptor instead. func (*PrepareRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{6} + return file_account_protos_auth_proto_rawDescGZIP(), []int{6} } func (x *PrepareRequest) GetEmail() string { @@ -419,7 +419,7 @@ type PrepareResponse struct { func (x *PrepareResponse) Reset() { *x = PrepareResponse{} - mi := &file_api_protos_auth_proto_msgTypes[7] + mi := &file_account_protos_auth_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -431,7 +431,7 @@ func (x *PrepareResponse) String() string { func (*PrepareResponse) ProtoMessage() {} func (x *PrepareResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[7] + mi := &file_account_protos_auth_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -444,7 +444,7 @@ func (x *PrepareResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareResponse.ProtoReflect.Descriptor instead. func (*PrepareResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{7} + return file_account_protos_auth_proto_rawDescGZIP(), []int{7} } func (x *PrepareResponse) GetB() []byte { @@ -473,7 +473,7 @@ type LoginRequest struct { func (x *LoginRequest) Reset() { *x = LoginRequest{} - mi := &file_api_protos_auth_proto_msgTypes[8] + mi := &file_account_protos_auth_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -485,7 +485,7 @@ func (x *LoginRequest) String() string { func (*LoginRequest) ProtoMessage() {} func (x *LoginRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[8] + mi := &file_account_protos_auth_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -498,7 +498,7 @@ func (x *LoginRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead. func (*LoginRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{8} + return file_account_protos_auth_proto_rawDescGZIP(), []int{8} } func (x *LoginRequest) GetEmail() string { @@ -541,7 +541,7 @@ type LoginResponse struct { func (x *LoginResponse) Reset() { *x = LoginResponse{} - mi := &file_api_protos_auth_proto_msgTypes[9] + mi := &file_account_protos_auth_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -553,7 +553,7 @@ func (x *LoginResponse) String() string { func (*LoginResponse) ProtoMessage() {} func (x *LoginResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[9] + mi := &file_account_protos_auth_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -566,7 +566,7 @@ func (x *LoginResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginResponse.ProtoReflect.Descriptor instead. func (*LoginResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{9} + return file_account_protos_auth_proto_rawDescGZIP(), []int{9} } func (x *LoginResponse) GetLegacyID() int64 { @@ -635,7 +635,7 @@ type StartRecoveryByEmailRequest struct { func (x *StartRecoveryByEmailRequest) Reset() { *x = StartRecoveryByEmailRequest{} - mi := &file_api_protos_auth_proto_msgTypes[10] + mi := &file_account_protos_auth_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -647,7 +647,7 @@ func (x *StartRecoveryByEmailRequest) String() string { func (*StartRecoveryByEmailRequest) ProtoMessage() {} func (x *StartRecoveryByEmailRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[10] + mi := &file_account_protos_auth_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -660,7 +660,7 @@ func (x *StartRecoveryByEmailRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StartRecoveryByEmailRequest.ProtoReflect.Descriptor instead. func (*StartRecoveryByEmailRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{10} + return file_account_protos_auth_proto_rawDescGZIP(), []int{10} } func (x *StartRecoveryByEmailRequest) GetEmail() string { @@ -683,7 +683,7 @@ type CompleteRecoveryByEmailRequest struct { func (x *CompleteRecoveryByEmailRequest) Reset() { *x = CompleteRecoveryByEmailRequest{} - mi := &file_api_protos_auth_proto_msgTypes[11] + mi := &file_account_protos_auth_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -695,7 +695,7 @@ func (x *CompleteRecoveryByEmailRequest) String() string { func (*CompleteRecoveryByEmailRequest) ProtoMessage() {} func (x *CompleteRecoveryByEmailRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[11] + mi := &file_account_protos_auth_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -708,7 +708,7 @@ func (x *CompleteRecoveryByEmailRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteRecoveryByEmailRequest.ProtoReflect.Descriptor instead. func (*CompleteRecoveryByEmailRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{11} + return file_account_protos_auth_proto_rawDescGZIP(), []int{11} } func (x *CompleteRecoveryByEmailRequest) GetEmail() string { @@ -751,7 +751,7 @@ type ChangeEmailRequest struct { func (x *ChangeEmailRequest) Reset() { *x = ChangeEmailRequest{} - mi := &file_api_protos_auth_proto_msgTypes[12] + mi := &file_account_protos_auth_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -763,7 +763,7 @@ func (x *ChangeEmailRequest) String() string { func (*ChangeEmailRequest) ProtoMessage() {} func (x *ChangeEmailRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[12] + mi := &file_account_protos_auth_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -776,7 +776,7 @@ func (x *ChangeEmailRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeEmailRequest.ProtoReflect.Descriptor instead. func (*ChangeEmailRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{12} + return file_account_protos_auth_proto_rawDescGZIP(), []int{12} } func (x *ChangeEmailRequest) GetOldEmail() string { @@ -814,7 +814,7 @@ type CompleteChangeEmailRequest struct { func (x *CompleteChangeEmailRequest) Reset() { *x = CompleteChangeEmailRequest{} - mi := &file_api_protos_auth_proto_msgTypes[13] + mi := &file_account_protos_auth_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -826,7 +826,7 @@ func (x *CompleteChangeEmailRequest) String() string { func (*CompleteChangeEmailRequest) ProtoMessage() {} func (x *CompleteChangeEmailRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[13] + mi := &file_account_protos_auth_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -839,7 +839,7 @@ func (x *CompleteChangeEmailRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteChangeEmailRequest.ProtoReflect.Descriptor instead. func (*CompleteChangeEmailRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{13} + return file_account_protos_auth_proto_rawDescGZIP(), []int{13} } func (x *CompleteChangeEmailRequest) GetOldEmail() string { @@ -891,7 +891,7 @@ type DeleteUserRequest struct { func (x *DeleteUserRequest) Reset() { *x = DeleteUserRequest{} - mi := &file_api_protos_auth_proto_msgTypes[14] + mi := &file_account_protos_auth_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -903,7 +903,7 @@ func (x *DeleteUserRequest) String() string { func (*DeleteUserRequest) ProtoMessage() {} func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[14] + mi := &file_account_protos_auth_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -916,7 +916,7 @@ func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. func (*DeleteUserRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{14} + return file_account_protos_auth_proto_rawDescGZIP(), []int{14} } func (x *DeleteUserRequest) GetEmail() string { @@ -965,7 +965,7 @@ type ValidateRecoveryCodeRequest struct { func (x *ValidateRecoveryCodeRequest) Reset() { *x = ValidateRecoveryCodeRequest{} - mi := &file_api_protos_auth_proto_msgTypes[15] + mi := &file_account_protos_auth_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -977,7 +977,7 @@ func (x *ValidateRecoveryCodeRequest) String() string { func (*ValidateRecoveryCodeRequest) ProtoMessage() {} func (x *ValidateRecoveryCodeRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[15] + mi := &file_account_protos_auth_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -990,7 +990,7 @@ func (x *ValidateRecoveryCodeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRecoveryCodeRequest.ProtoReflect.Descriptor instead. func (*ValidateRecoveryCodeRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{15} + return file_account_protos_auth_proto_rawDescGZIP(), []int{15} } func (x *ValidateRecoveryCodeRequest) GetEmail() string { @@ -1016,7 +1016,7 @@ type ValidateRecoveryCodeResponse struct { func (x *ValidateRecoveryCodeResponse) Reset() { *x = ValidateRecoveryCodeResponse{} - mi := &file_api_protos_auth_proto_msgTypes[16] + mi := &file_account_protos_auth_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1028,7 +1028,7 @@ func (x *ValidateRecoveryCodeResponse) String() string { func (*ValidateRecoveryCodeResponse) ProtoMessage() {} func (x *ValidateRecoveryCodeResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[16] + mi := &file_account_protos_auth_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1041,7 +1041,7 @@ func (x *ValidateRecoveryCodeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRecoveryCodeResponse.ProtoReflect.Descriptor instead. func (*ValidateRecoveryCodeResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{16} + return file_account_protos_auth_proto_rawDescGZIP(), []int{16} } func (x *ValidateRecoveryCodeResponse) GetValid() bool { @@ -1065,7 +1065,7 @@ type LogoutRequest struct { func (x *LogoutRequest) Reset() { *x = LogoutRequest{} - mi := &file_api_protos_auth_proto_msgTypes[17] + mi := &file_account_protos_auth_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1077,7 +1077,7 @@ func (x *LogoutRequest) String() string { func (*LogoutRequest) ProtoMessage() {} func (x *LogoutRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[17] + mi := &file_account_protos_auth_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1090,7 +1090,7 @@ func (x *LogoutRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LogoutRequest.ProtoReflect.Descriptor instead. func (*LogoutRequest) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{17} + return file_account_protos_auth_proto_rawDescGZIP(), []int{17} } func (x *LogoutRequest) GetEmail() string { @@ -1140,7 +1140,7 @@ type BaseResponse struct { func (x *BaseResponse) Reset() { *x = BaseResponse{} - mi := &file_api_protos_auth_proto_msgTypes[18] + mi := &file_account_protos_auth_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1152,7 +1152,7 @@ func (x *BaseResponse) String() string { func (*BaseResponse) ProtoMessage() {} func (x *BaseResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[18] + mi := &file_account_protos_auth_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1165,7 +1165,7 @@ func (x *BaseResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BaseResponse.ProtoReflect.Descriptor instead. func (*BaseResponse) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{18} + return file_account_protos_auth_proto_rawDescGZIP(), []int{18} } func (x *BaseResponse) GetStatus() string { @@ -1198,7 +1198,7 @@ type Purchase struct { func (x *Purchase) Reset() { *x = Purchase{} - mi := &file_api_protos_auth_proto_msgTypes[19] + mi := &file_account_protos_auth_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1210,7 +1210,7 @@ func (x *Purchase) String() string { func (*Purchase) ProtoMessage() {} func (x *Purchase) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[19] + mi := &file_account_protos_auth_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1223,7 +1223,7 @@ func (x *Purchase) ProtoReflect() protoreflect.Message { // Deprecated: Use Purchase.ProtoReflect.Descriptor instead. func (*Purchase) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{19} + return file_account_protos_auth_proto_rawDescGZIP(), []int{19} } func (x *Purchase) GetPlan() string { @@ -1244,7 +1244,7 @@ type LoginResponse_Device struct { func (x *LoginResponse_Device) Reset() { *x = LoginResponse_Device{} - mi := &file_api_protos_auth_proto_msgTypes[20] + mi := &file_account_protos_auth_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1256,7 +1256,7 @@ func (x *LoginResponse_Device) String() string { func (*LoginResponse_Device) ProtoMessage() {} func (x *LoginResponse_Device) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[20] + mi := &file_account_protos_auth_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1269,7 +1269,7 @@ func (x *LoginResponse_Device) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginResponse_Device.ProtoReflect.Descriptor instead. func (*LoginResponse_Device) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{9, 0} + return file_account_protos_auth_proto_rawDescGZIP(), []int{9, 0} } func (x *LoginResponse_Device) GetId() string { @@ -1299,7 +1299,7 @@ type LoginResponse_UserData struct { Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"` Referral string `protobuf:"bytes,4,opt,name=referral,proto3" json:"referral,omitempty"` - // Deprecated: Marked as deprecated in api/protos/auth.proto. + // Deprecated: Marked as deprecated in account/protos/auth.proto. Phone string `protobuf:"bytes,5,opt,name=phone,proto3" json:"phone,omitempty"` // not used anymore Email string `protobuf:"bytes,6,opt,name=email,proto3" json:"email,omitempty"` UserStatus string `protobuf:"bytes,7,opt,name=userStatus,proto3" json:"userStatus,omitempty"` @@ -1326,7 +1326,7 @@ type LoginResponse_UserData struct { func (x *LoginResponse_UserData) Reset() { *x = LoginResponse_UserData{} - mi := &file_api_protos_auth_proto_msgTypes[21] + mi := &file_account_protos_auth_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1338,7 +1338,7 @@ func (x *LoginResponse_UserData) String() string { func (*LoginResponse_UserData) ProtoMessage() {} func (x *LoginResponse_UserData) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[21] + mi := &file_account_protos_auth_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1351,7 +1351,7 @@ func (x *LoginResponse_UserData) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginResponse_UserData.ProtoReflect.Descriptor instead. func (*LoginResponse_UserData) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{9, 1} + return file_account_protos_auth_proto_rawDescGZIP(), []int{9, 1} } func (x *LoginResponse_UserData) GetUserId() int64 { @@ -1382,7 +1382,7 @@ func (x *LoginResponse_UserData) GetReferral() string { return "" } -// Deprecated: Marked as deprecated in api/protos/auth.proto. +// Deprecated: Marked as deprecated in account/protos/auth.proto. func (x *LoginResponse_UserData) GetPhone() string { if x != nil { return x.Phone @@ -1528,7 +1528,7 @@ type LoginResponse_UserData_SubscriptionData struct { func (x *LoginResponse_UserData_SubscriptionData) Reset() { *x = LoginResponse_UserData_SubscriptionData{} - mi := &file_api_protos_auth_proto_msgTypes[22] + mi := &file_account_protos_auth_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1540,7 +1540,7 @@ func (x *LoginResponse_UserData_SubscriptionData) String() string { func (*LoginResponse_UserData_SubscriptionData) ProtoMessage() {} func (x *LoginResponse_UserData_SubscriptionData) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_auth_proto_msgTypes[22] + mi := &file_account_protos_auth_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1553,7 +1553,7 @@ func (x *LoginResponse_UserData_SubscriptionData) ProtoReflect() protoreflect.Me // Deprecated: Use LoginResponse_UserData_SubscriptionData.ProtoReflect.Descriptor instead. func (*LoginResponse_UserData_SubscriptionData) Descriptor() ([]byte, []int) { - return file_api_protos_auth_proto_rawDescGZIP(), []int{9, 1, 0} + return file_account_protos_auth_proto_rawDescGZIP(), []int{9, 1, 0} } func (x *LoginResponse_UserData_SubscriptionData) GetSubscriptionID() string { @@ -1633,11 +1633,11 @@ func (x *LoginResponse_UserData_SubscriptionData) GetProvider() string { return "" } -var File_api_protos_auth_proto protoreflect.FileDescriptor +var File_account_protos_auth_proto protoreflect.FileDescriptor -const file_api_protos_auth_proto_rawDesc = "" + +const file_account_protos_auth_proto_rawDesc = "" + "\n" + - "\x15api/protos/auth.proto\"\xa1\x01\n" + + "\x19account/protos/auth.proto\"\xa1\x01\n" + "\rSignupRequest\x12\x14\n" + "\x05email\x18\x01 \x01(\tR\x05email\x12\x12\n" + "\x04salt\x18\x02 \x01(\fR\x04salt\x12\x1a\n" + @@ -1764,19 +1764,19 @@ const file_api_protos_auth_proto_rawDesc = "" + "\x04plan\x18\x01 \x01(\tR\x04planB\tZ\a/protosb\x06proto3" var ( - file_api_protos_auth_proto_rawDescOnce sync.Once - file_api_protos_auth_proto_rawDescData []byte + file_account_protos_auth_proto_rawDescOnce sync.Once + file_account_protos_auth_proto_rawDescData []byte ) -func file_api_protos_auth_proto_rawDescGZIP() []byte { - file_api_protos_auth_proto_rawDescOnce.Do(func() { - file_api_protos_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_protos_auth_proto_rawDesc), len(file_api_protos_auth_proto_rawDesc))) +func file_account_protos_auth_proto_rawDescGZIP() []byte { + file_account_protos_auth_proto_rawDescOnce.Do(func() { + file_account_protos_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_account_protos_auth_proto_rawDesc), len(file_account_protos_auth_proto_rawDesc))) }) - return file_api_protos_auth_proto_rawDescData + return file_account_protos_auth_proto_rawDescData } -var file_api_protos_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 23) -var file_api_protos_auth_proto_goTypes = []any{ +var file_account_protos_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_account_protos_auth_proto_goTypes = []any{ (*SignupRequest)(nil), // 0: SignupRequest (*SignupResponse)(nil), // 1: SignupResponse (*EmptyResponse)(nil), // 2: EmptyResponse @@ -1801,7 +1801,7 @@ var file_api_protos_auth_proto_goTypes = []any{ (*LoginResponse_UserData)(nil), // 21: LoginResponse.UserData (*LoginResponse_UserData_SubscriptionData)(nil), // 22: LoginResponse.UserData.SubscriptionData } -var file_api_protos_auth_proto_depIdxs = []int32{ +var file_account_protos_auth_proto_depIdxs = []int32{ 21, // 0: LoginResponse.legacyUserData:type_name -> LoginResponse.UserData 20, // 1: LoginResponse.devices:type_name -> LoginResponse.Device 20, // 2: LoginResponse.UserData.devices:type_name -> LoginResponse.Device @@ -1813,26 +1813,26 @@ var file_api_protos_auth_proto_depIdxs = []int32{ 0, // [0:4] is the sub-list for field type_name } -func init() { file_api_protos_auth_proto_init() } -func file_api_protos_auth_proto_init() { - if File_api_protos_auth_proto != nil { +func init() { file_account_protos_auth_proto_init() } +func file_account_protos_auth_proto_init() { + if File_account_protos_auth_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_protos_auth_proto_rawDesc), len(file_api_protos_auth_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_account_protos_auth_proto_rawDesc), len(file_account_protos_auth_proto_rawDesc)), NumEnums: 0, NumMessages: 23, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_api_protos_auth_proto_goTypes, - DependencyIndexes: file_api_protos_auth_proto_depIdxs, - MessageInfos: file_api_protos_auth_proto_msgTypes, + GoTypes: file_account_protos_auth_proto_goTypes, + DependencyIndexes: file_account_protos_auth_proto_depIdxs, + MessageInfos: file_account_protos_auth_proto_msgTypes, }.Build() - File_api_protos_auth_proto = out.File - file_api_protos_auth_proto_goTypes = nil - file_api_protos_auth_proto_depIdxs = nil + File_account_protos_auth_proto = out.File + file_account_protos_auth_proto_goTypes = nil + file_account_protos_auth_proto_depIdxs = nil } diff --git a/account/protos/subscription.pb.go b/account/protos/subscription.pb.go index 82e04d52..ec81917c 100644 --- a/account/protos/subscription.pb.go +++ b/account/protos/subscription.pb.go @@ -1,8 +1,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 +// protoc-gen-go v1.36.11 // protoc v5.28.3 -// source: api/protos/subscription.proto +// source: account/protos/subscription.proto package protos @@ -22,26 +22,31 @@ const ( ) type Plan struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - BestValue bool `protobuf:"varint,3,opt,name=bestValue,proto3" json:"bestValue,omitempty"` - UsdPrice int64 `protobuf:"varint,4,opt,name=usdPrice,proto3" json:"usdPrice,omitempty"` - Price map[string]int64 `protobuf:"bytes,5,rep,name=price,proto3" json:"price,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - ExpectedMonthlyPrice map[string]int64 `protobuf:"bytes,6,rep,name=expectedMonthlyPrice,proto3" json:"expectedMonthlyPrice,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - TotalCostBilledOneTime string `protobuf:"bytes,7,opt,name=totalCostBilledOneTime,proto3" json:"totalCostBilledOneTime,omitempty"` - OneMonthCost string `protobuf:"bytes,8,opt,name=oneMonthCost,proto3" json:"oneMonthCost,omitempty"` - TotalCost string `protobuf:"bytes,9,opt,name=totalCost,proto3" json:"totalCost,omitempty"` - FormattedBonus string `protobuf:"bytes,10,opt,name=formattedBonus,proto3" json:"formattedBonus,omitempty"` - RenewalText string `protobuf:"bytes,11,opt,name=renewalText,proto3" json:"renewalText,omitempty"` - RenewalBonusExpected map[string]int64 `protobuf:"bytes,13,rep,name=renewalBonusExpected,proto3" json:"renewalBonusExpected,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + BestValue bool `protobuf:"varint,3,opt,name=bestValue,proto3" json:"bestValue,omitempty"` + UsdPrice int64 `protobuf:"varint,4,opt,name=usdPrice,proto3" json:"usdPrice,omitempty"` + Price map[string]int64 `protobuf:"bytes,5,rep,name=price,proto3" json:"price,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + ExpectedMonthlyPrice map[string]int64 `protobuf:"bytes,6,rep,name=expectedMonthlyPrice,proto3" json:"expectedMonthlyPrice,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + TotalCostBilledOneTime string `protobuf:"bytes,7,opt,name=totalCostBilledOneTime,proto3" json:"totalCostBilledOneTime,omitempty"` + OneMonthCost string `protobuf:"bytes,8,opt,name=oneMonthCost,proto3" json:"oneMonthCost,omitempty"` + TotalCost string `protobuf:"bytes,9,opt,name=totalCost,proto3" json:"totalCost,omitempty"` + FormattedBonus string `protobuf:"bytes,10,opt,name=formattedBonus,proto3" json:"formattedBonus,omitempty"` + RenewalText string `protobuf:"bytes,11,opt,name=renewalText,proto3" json:"renewalText,omitempty"` + RenewalBonusExpected map[string]int64 `protobuf:"bytes,13,rep,name=renewalBonusExpected,proto3" json:"renewalBonusExpected,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + OriginalUsdPrice int64 `protobuf:"varint,14,opt,name=originalUsdPrice,proto3" json:"originalUsdPrice,omitempty"` + OriginalUsdPrice1Y int64 `protobuf:"varint,15,opt,name=originalUsdPrice1Y,proto3" json:"originalUsdPrice1Y,omitempty"` + OriginalUsdPrice2Y int64 `protobuf:"varint,16,opt,name=originalUsdPrice2Y,proto3" json:"originalUsdPrice2Y,omitempty"` + OriginalPrice map[string]int64 `protobuf:"bytes,17,rep,name=originalPrice,proto3" json:"originalPrice,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + OriginalExpectedMonthlyPrice map[string]int64 `protobuf:"bytes,18,rep,name=originalExpectedMonthlyPrice,proto3" json:"originalExpectedMonthlyPrice,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Plan) Reset() { *x = Plan{} - mi := &file_api_protos_subscription_proto_msgTypes[0] + mi := &file_account_protos_subscription_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -53,7 +58,7 @@ func (x *Plan) String() string { func (*Plan) ProtoMessage() {} func (x *Plan) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_subscription_proto_msgTypes[0] + mi := &file_account_protos_subscription_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -66,7 +71,7 @@ func (x *Plan) ProtoReflect() protoreflect.Message { // Deprecated: Use Plan.ProtoReflect.Descriptor instead. func (*Plan) Descriptor() ([]byte, []int) { - return file_api_protos_subscription_proto_rawDescGZIP(), []int{0} + return file_account_protos_subscription_proto_rawDescGZIP(), []int{0} } func (x *Plan) GetId() string { @@ -153,6 +158,41 @@ func (x *Plan) GetRenewalBonusExpected() map[string]int64 { return nil } +func (x *Plan) GetOriginalUsdPrice() int64 { + if x != nil { + return x.OriginalUsdPrice + } + return 0 +} + +func (x *Plan) GetOriginalUsdPrice1Y() int64 { + if x != nil { + return x.OriginalUsdPrice1Y + } + return 0 +} + +func (x *Plan) GetOriginalUsdPrice2Y() int64 { + if x != nil { + return x.OriginalUsdPrice2Y + } + return 0 +} + +func (x *Plan) GetOriginalPrice() map[string]int64 { + if x != nil { + return x.OriginalPrice + } + return nil +} + +func (x *Plan) GetOriginalExpectedMonthlyPrice() map[string]int64 { + if x != nil { + return x.OriginalExpectedMonthlyPrice + } + return nil +} + type PaymentProviders struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -165,7 +205,7 @@ type PaymentProviders struct { func (x *PaymentProviders) Reset() { *x = PaymentProviders{} - mi := &file_api_protos_subscription_proto_msgTypes[1] + mi := &file_account_protos_subscription_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -177,7 +217,7 @@ func (x *PaymentProviders) String() string { func (*PaymentProviders) ProtoMessage() {} func (x *PaymentProviders) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_subscription_proto_msgTypes[1] + mi := &file_account_protos_subscription_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -190,7 +230,7 @@ func (x *PaymentProviders) ProtoReflect() protoreflect.Message { // Deprecated: Use PaymentProviders.ProtoReflect.Descriptor instead. func (*PaymentProviders) Descriptor() ([]byte, []int) { - return file_api_protos_subscription_proto_rawDescGZIP(), []int{1} + return file_account_protos_subscription_proto_rawDescGZIP(), []int{1} } func (x *PaymentProviders) GetName() string { @@ -231,7 +271,7 @@ type PaymentMethod struct { func (x *PaymentMethod) Reset() { *x = PaymentMethod{} - mi := &file_api_protos_subscription_proto_msgTypes[2] + mi := &file_account_protos_subscription_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -243,7 +283,7 @@ func (x *PaymentMethod) String() string { func (*PaymentMethod) ProtoMessage() {} func (x *PaymentMethod) ProtoReflect() protoreflect.Message { - mi := &file_api_protos_subscription_proto_msgTypes[2] + mi := &file_account_protos_subscription_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -256,7 +296,7 @@ func (x *PaymentMethod) ProtoReflect() protoreflect.Message { // Deprecated: Use PaymentMethod.ProtoReflect.Descriptor instead. func (*PaymentMethod) Descriptor() ([]byte, []int) { - return file_api_protos_subscription_proto_rawDescGZIP(), []int{2} + return file_account_protos_subscription_proto_rawDescGZIP(), []int{2} } func (x *PaymentMethod) GetMethod() string { @@ -273,11 +313,11 @@ func (x *PaymentMethod) GetProvider() *PaymentProviders { return nil } -var File_api_protos_subscription_proto protoreflect.FileDescriptor +var File_account_protos_subscription_proto protoreflect.FileDescriptor -const file_api_protos_subscription_proto_rawDesc = "" + +const file_account_protos_subscription_proto_rawDesc = "" + "\n" + - "\x1dapi/protos/subscription.proto\"\xd4\x05\n" + + "!account/protos/subscription.proto\"\xa0\t\n" + "\x04Plan\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12 \n" + "\vdescription\x18\x02 \x01(\tR\vdescription\x12\x1c\n" + @@ -291,7 +331,12 @@ const file_api_protos_subscription_proto_rawDesc = "" + "\x0eformattedBonus\x18\n" + " \x01(\tR\x0eformattedBonus\x12 \n" + "\vrenewalText\x18\v \x01(\tR\vrenewalText\x12S\n" + - "\x14renewalBonusExpected\x18\r \x03(\v2\x1f.Plan.RenewalBonusExpectedEntryR\x14renewalBonusExpected\x1a8\n" + + "\x14renewalBonusExpected\x18\r \x03(\v2\x1f.Plan.RenewalBonusExpectedEntryR\x14renewalBonusExpected\x12*\n" + + "\x10originalUsdPrice\x18\x0e \x01(\x03R\x10originalUsdPrice\x12.\n" + + "\x12originalUsdPrice1Y\x18\x0f \x01(\x03R\x12originalUsdPrice1Y\x12.\n" + + "\x12originalUsdPrice2Y\x18\x10 \x01(\x03R\x12originalUsdPrice2Y\x12>\n" + + "\roriginalPrice\x18\x11 \x03(\v2\x18.Plan.OriginalPriceEntryR\roriginalPrice\x12k\n" + + "\x1coriginalExpectedMonthlyPrice\x18\x12 \x03(\v2'.Plan.OriginalExpectedMonthlyPriceEntryR\x1coriginalExpectedMonthlyPrice\x1a8\n" + "\n" + "PriceEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + @@ -301,6 +346,12 @@ const file_api_protos_subscription_proto_rawDesc = "" + "\x05value\x18\x02 \x01(\x03R\x05value:\x028\x01\x1aG\n" + "\x19RenewalBonusExpectedEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\x03R\x05value:\x028\x01\x1a@\n" + + "\x12OriginalPriceEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\x03R\x05value:\x028\x01\x1aO\n" + + "!OriginalExpectedMonthlyPriceEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\x03R\x05value:\x028\x01\"\xda\x01\n" + "\x10PaymentProviders\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + @@ -315,60 +366,64 @@ const file_api_protos_subscription_proto_rawDesc = "" + "\bprovider\x18\x02 \x01(\v2\x11.PaymentProvidersR\bproviderB\tZ\a/protosb\x06proto3" var ( - file_api_protos_subscription_proto_rawDescOnce sync.Once - file_api_protos_subscription_proto_rawDescData []byte + file_account_protos_subscription_proto_rawDescOnce sync.Once + file_account_protos_subscription_proto_rawDescData []byte ) -func file_api_protos_subscription_proto_rawDescGZIP() []byte { - file_api_protos_subscription_proto_rawDescOnce.Do(func() { - file_api_protos_subscription_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_api_protos_subscription_proto_rawDesc), len(file_api_protos_subscription_proto_rawDesc))) +func file_account_protos_subscription_proto_rawDescGZIP() []byte { + file_account_protos_subscription_proto_rawDescOnce.Do(func() { + file_account_protos_subscription_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_account_protos_subscription_proto_rawDesc), len(file_account_protos_subscription_proto_rawDesc))) }) - return file_api_protos_subscription_proto_rawDescData + return file_account_protos_subscription_proto_rawDescData } -var file_api_protos_subscription_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_api_protos_subscription_proto_goTypes = []any{ +var file_account_protos_subscription_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_account_protos_subscription_proto_goTypes = []any{ (*Plan)(nil), // 0: Plan (*PaymentProviders)(nil), // 1: PaymentProviders (*PaymentMethod)(nil), // 2: PaymentMethod nil, // 3: Plan.PriceEntry nil, // 4: Plan.ExpectedMonthlyPriceEntry nil, // 5: Plan.RenewalBonusExpectedEntry - nil, // 6: PaymentProviders.DataEntry + nil, // 6: Plan.OriginalPriceEntry + nil, // 7: Plan.OriginalExpectedMonthlyPriceEntry + nil, // 8: PaymentProviders.DataEntry } -var file_api_protos_subscription_proto_depIdxs = []int32{ +var file_account_protos_subscription_proto_depIdxs = []int32{ 3, // 0: Plan.price:type_name -> Plan.PriceEntry 4, // 1: Plan.expectedMonthlyPrice:type_name -> Plan.ExpectedMonthlyPriceEntry 5, // 2: Plan.renewalBonusExpected:type_name -> Plan.RenewalBonusExpectedEntry - 6, // 3: PaymentProviders.data:type_name -> PaymentProviders.DataEntry - 1, // 4: PaymentMethod.provider:type_name -> PaymentProviders - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_api_protos_subscription_proto_init() } -func file_api_protos_subscription_proto_init() { - if File_api_protos_subscription_proto != nil { + 6, // 3: Plan.originalPrice:type_name -> Plan.OriginalPriceEntry + 7, // 4: Plan.originalExpectedMonthlyPrice:type_name -> Plan.OriginalExpectedMonthlyPriceEntry + 8, // 5: PaymentProviders.data:type_name -> PaymentProviders.DataEntry + 1, // 6: PaymentMethod.provider:type_name -> PaymentProviders + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_account_protos_subscription_proto_init() } +func file_account_protos_subscription_proto_init() { + if File_account_protos_subscription_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_protos_subscription_proto_rawDesc), len(file_api_protos_subscription_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_account_protos_subscription_proto_rawDesc), len(file_account_protos_subscription_proto_rawDesc)), NumEnums: 0, - NumMessages: 7, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_api_protos_subscription_proto_goTypes, - DependencyIndexes: file_api_protos_subscription_proto_depIdxs, - MessageInfos: file_api_protos_subscription_proto_msgTypes, + GoTypes: file_account_protos_subscription_proto_goTypes, + DependencyIndexes: file_account_protos_subscription_proto_depIdxs, + MessageInfos: file_account_protos_subscription_proto_msgTypes, }.Build() - File_api_protos_subscription_proto = out.File - file_api_protos_subscription_proto_goTypes = nil - file_api_protos_subscription_proto_depIdxs = nil + File_account_protos_subscription_proto = out.File + file_account_protos_subscription_proto_goTypes = nil + file_account_protos_subscription_proto_depIdxs = nil } diff --git a/account/protos/subscription.proto b/account/protos/subscription.proto index 822cc605..4700a4fc 100644 --- a/account/protos/subscription.proto +++ b/account/protos/subscription.proto @@ -14,6 +14,11 @@ message Plan { string formattedBonus = 10; string renewalText = 11; map renewalBonusExpected = 13; + int64 originalUsdPrice = 14; + int64 originalUsdPrice1Y = 15; + int64 originalUsdPrice2Y = 16; + map originalPrice = 17; + map originalExpectedMonthlyPrice = 18; } message PaymentProviders { diff --git a/account/subscription.go b/account/subscription.go index a1d20415..7cdf3915 100644 --- a/account/subscription.go +++ b/account/subscription.go @@ -40,6 +40,7 @@ type PaymentRedirectData struct { DeviceName string `json:"deviceName" validate:"required" errorId:"device-name"` BillingType SubscriptionType `json:"billingType"` IdempotencyKey string `json:"idempotencyKey"` + CouponCode string `json:"couponCode"` } type SubscriptionPlans struct { @@ -83,7 +84,7 @@ func (a *Client) SubscriptionPlans(ctx context.Context, channel string) (string, } // NewStripeSubscription creates a new Stripe subscription for the given email and plan ID. -func (a *Client) NewStripeSubscription(ctx context.Context, email, planID string) (string, error) { +func (a *Client) NewStripeSubscription(ctx context.Context, email, planID, couponCode string) (string, error) { ctx, span := otel.Tracer(tracerName).Start(ctx, "new_stripe_subscription") defer span.End() @@ -91,6 +92,9 @@ func (a *Client) NewStripeSubscription(ctx context.Context, email, planID string "email": email, "planId": planID, } + if couponCode != "" { + data["couponCode"] = couponCode + } resp, err := a.sendProRequest(ctx, "POST", "/stripe-subscription", nil, nil, data) if err != nil { return "", traces.RecordError(ctx, fmt.Errorf("creating stripe subscription: %w", err)) @@ -226,6 +230,9 @@ func (a *Client) SubscriptionPaymentRedirectURL(ctx context.Context, data Paymen if data.IdempotencyKey != "" { params["idempotencyKey"] = data.IdempotencyKey } + if data.CouponCode != "" { + params["couponCode"] = data.CouponCode + } return a.paymentRedirect(ctx, "/subscription-payment-redirect", params) } @@ -243,6 +250,9 @@ func (a *Client) PaymentRedirect(ctx context.Context, data PaymentRedirectData) if data.IdempotencyKey != "" { params["idempotencyKey"] = data.IdempotencyKey } + if data.CouponCode != "" { + params["couponCode"] = data.CouponCode + } return a.paymentRedirect(ctx, "/payment-redirect", params) } diff --git a/account/subscription_test.go b/account/subscription_test.go index 8a4bcae7..1d074bb2 100644 --- a/account/subscription_test.go +++ b/account/subscription_test.go @@ -59,6 +59,43 @@ func TestPaymentRedirectOmitsEmptyIdempotencyKey(t *testing.T) { assert.False(t, ts.subscriptionPaymentRedirectHasIdempotencyKey) } +func TestPaymentRedirectForwardsCouponCode(t *testing.T) { + ac, ts := newTestClient(t) + data := PaymentRedirectData{ + Provider: "stripe", + Plan: "pro", + DeviceName: "test-device", + CouponCode: "SAVE20", + } + + _, err := ac.PaymentRedirect(context.Background(), data) + require.NoError(t, err) + assert.True(t, ts.paymentRedirectHasCouponCode) + assert.Equal(t, data.CouponCode, ts.paymentRedirectCouponCode) + + _, err = ac.SubscriptionPaymentRedirectURL(context.Background(), data) + require.NoError(t, err) + assert.True(t, ts.subscriptionPaymentRedirectHasCouponCode) + assert.Equal(t, data.CouponCode, ts.subscriptionPaymentRedirectCouponCode) +} + +func TestPaymentRedirectOmitsEmptyCouponCode(t *testing.T) { + ac, ts := newTestClient(t) + data := PaymentRedirectData{ + Provider: "stripe", + Plan: "pro", + DeviceName: "test-device", + } + + _, err := ac.PaymentRedirect(context.Background(), data) + require.NoError(t, err) + assert.False(t, ts.paymentRedirectHasCouponCode) + + _, err = ac.SubscriptionPaymentRedirectURL(context.Background(), data) + require.NoError(t, err) + assert.False(t, ts.subscriptionPaymentRedirectHasCouponCode) +} + func TestPaymentRedirectRequiresRedirectURL(t *testing.T) { ac, ts := newTestClient(t) ts.paymentRedirectResponse = map[string]string{"status": "error", "error": "try again later"} @@ -123,3 +160,20 @@ func TestPlans(t *testing.T) { require.NoError(t, err) assert.NotEmpty(t, resp) } + +func TestNewStripeSubscriptionForwardsCouponCode(t *testing.T) { + ac, ts := newTestClient(t) + resp, err := ac.NewStripeSubscription(context.Background(), "test@getlantern.org", "1y-usd-10", "SAVE20") + require.NoError(t, err) + assert.NotEmpty(t, resp) + assert.True(t, ts.stripeSubscriptionHasCouponCode) + assert.Equal(t, "SAVE20", ts.stripeSubscriptionCouponCode) +} + +func TestNewStripeSubscriptionOmitsEmptyCouponCode(t *testing.T) { + ac, ts := newTestClient(t) + resp, err := ac.NewStripeSubscription(context.Background(), "test@getlantern.org", "1y-usd-10", "") + require.NoError(t, err) + assert.NotEmpty(t, resp) + assert.False(t, ts.stripeSubscriptionHasCouponCode) +} diff --git a/account/user.go b/account/user.go index 83dc7769..fc9df3bd 100644 --- a/account/user.go +++ b/account/user.go @@ -600,7 +600,26 @@ func (a *Client) RemoveDevice(ctx context.Context, deviceID string) (*LinkRespon return &link, nil } -func (a *Client) ReferralAttach(ctx context.Context, code string) (bool, error) { +type ReferralAttachResponse struct { + *protos.BaseResponse `json:",inline"` + Providers map[string][]*protos.PaymentMethod `json:"providers"` + Plans []*protos.Plan `json:"plans"` + Code string `json:"code"` + DiscountPct int `json:"discountPct"` + Type string `json:"referralType"` +} + +// ReferralAttach attaches a referral code to the current user. A non-empty +// channel uses the v2 API, which also returns the plans, providers, and +// discount for the referral; the legacy v1 API returns only a BaseResponse. +func (a *Client) ReferralAttach(ctx context.Context, code, channel string) (*ReferralAttachResponse, error) { + if channel == "" { + return a.referralAttachV1(ctx, code) + } + return a.referralAttachV2(ctx, code, channel) +} + +func (a *Client) referralAttachV1(ctx context.Context, code string) (*ReferralAttachResponse, error) { ctx, span := otel.Tracer(tracerName).Start(ctx, "referral_attach") defer span.End() @@ -609,16 +628,42 @@ func (a *Client) ReferralAttach(ctx context.Context, code string) (bool, error) } resp, err := a.sendProRequest(ctx, "POST", "/referral-attach", nil, nil, data) if err != nil { - return false, traces.RecordError(ctx, err) + return nil, traces.RecordError(ctx, err) } var baseResp protos.BaseResponse if err := proto.Unmarshal(resp, &baseResp); err != nil { - return false, traces.RecordError(ctx, fmt.Errorf("error unmarshalling referral attach response: %w", err)) + return nil, traces.RecordError(ctx, fmt.Errorf("error unmarshalling referral attach response: %w", err)) } if baseResp.Error != "" { - return false, traces.RecordError(ctx, errors.New(baseResp.Error)) + return nil, traces.RecordError(ctx, errors.New(baseResp.Error)) + } + return &ReferralAttachResponse{ + BaseResponse: &baseResp, + }, nil +} + +func (a *Client) referralAttachV2(ctx context.Context, code, channel string) (*ReferralAttachResponse, error) { + ctx, span := otel.Tracer(tracerName).Start(ctx, "referral_attach_v2") + defer span.End() + + params := map[string]string{ + "distributionChannel": channel, + } + data := map[string]string{ + "code": code, + } + resp, err := a.sendProRequest(ctx, "POST", "/referral-attach-v2", params, nil, data) + if err != nil { + return nil, traces.RecordError(ctx, err) + } + var referral ReferralAttachResponse + if err := json.Unmarshal(resp, &referral); err != nil { + return nil, traces.RecordError(ctx, fmt.Errorf("error unmarshalling referral attach v2 response: %w", err)) + } + if referral.BaseResponse != nil && referral.Error != "" { + return nil, traces.RecordError(ctx, errors.New(referral.Error)) } - return true, nil + return &referral, nil } type UserChangeEvent struct { diff --git a/account/user_test.go b/account/user_test.go index 89223f13..f249f5c7 100644 --- a/account/user_test.go +++ b/account/user_test.go @@ -27,8 +27,19 @@ type testServer struct { cache map[string]string paymentRedirectIdempotencyKey string paymentRedirectHasIdempotencyKey bool + paymentRedirectCouponCode string + paymentRedirectHasCouponCode bool subscriptionPaymentRedirectIdempotencyKey string subscriptionPaymentRedirectHasIdempotencyKey bool + subscriptionPaymentRedirectCouponCode string + subscriptionPaymentRedirectHasCouponCode bool + stripeSubscriptionCouponCode string + stripeSubscriptionHasCouponCode bool + referralAttachV1Code string + referralAttachV1Error string + referralAttachV2Code string + referralAttachV2Channel string + referralAttachV2Error string paymentRedirectResponse any } @@ -173,7 +184,28 @@ func newTestServer(t *testing.T) (*httptest.Server, *testServer) { }) mux.HandleFunc("/referral-attach", func(w http.ResponseWriter, r *http.Request) { - writeJSONResponse(w, protos.BaseResponse{}) + var body struct { + Code string `json:"code"` + } + json.NewDecoder(r.Body).Decode(&body) + state.referralAttachV1Code = body.Code + writeProtoResponse(w, &protos.BaseResponse{Error: state.referralAttachV1Error}) + }) + + mux.HandleFunc("/referral-attach-v2", func(w http.ResponseWriter, r *http.Request) { + state.referralAttachV2Channel = r.URL.Query().Get("distributionChannel") + var body struct { + Code string `json:"code"` + } + json.NewDecoder(r.Body).Decode(&body) + state.referralAttachV2Code = body.Code + writeJSONResponse(w, ReferralAttachResponse{ + BaseResponse: &protos.BaseResponse{Error: state.referralAttachV2Error}, + Code: body.Code, + DiscountPct: 20, + Type: "affiliate", + Plans: []*protos.Plan{{Id: "1y-usd-10", Description: "Pro Plan"}}, + }) }) // Subscription endpoints @@ -188,6 +220,8 @@ func newTestServer(t *testing.T) (*httptest.Server, *testServer) { values := r.URL.Query() state.subscriptionPaymentRedirectIdempotencyKey = values.Get("idempotencyKey") _, state.subscriptionPaymentRedirectHasIdempotencyKey = values["idempotencyKey"] + state.subscriptionPaymentRedirectCouponCode = values.Get("couponCode") + _, state.subscriptionPaymentRedirectHasCouponCode = values["couponCode"] writeJSONResponse(w, map[string]string{"redirect": "https://example.com/redirect"}) }) @@ -195,6 +229,8 @@ func newTestServer(t *testing.T) (*httptest.Server, *testServer) { values := r.URL.Query() state.paymentRedirectIdempotencyKey = values.Get("idempotencyKey") _, state.paymentRedirectHasIdempotencyKey = values["idempotencyKey"] + state.paymentRedirectCouponCode = values.Get("couponCode") + _, state.paymentRedirectHasCouponCode = values["couponCode"] resp := state.paymentRedirectResponse if resp == nil { resp = map[string]string{"redirect": "https://example.com/redirect"} @@ -203,6 +239,9 @@ func newTestServer(t *testing.T) (*httptest.Server, *testServer) { }) mux.HandleFunc("/stripe-subscription", func(w http.ResponseWriter, r *http.Request) { + var body map[string]string + json.NewDecoder(r.Body).Decode(&body) + state.stripeSubscriptionCouponCode, state.stripeSubscriptionHasCouponCode = body["couponCode"] writeJSONResponse(w, SubscriptionResponse{ CustomerID: "cus_123", SubscriptionID: "sub_123", @@ -394,3 +433,44 @@ func TestOAuthLoginCallback_InvalidToken(t *testing.T) { assert.Error(t, err) assert.Contains(t, err.Error(), "error decoding JWT") } + +func TestReferralAttach_EmptyChannelUsesV1(t *testing.T) { + ac, ts := newTestClient(t) + resp, err := ac.ReferralAttach(context.Background(), "AFF123", "") + require.NoError(t, err) + require.NotNil(t, resp) + assert.Equal(t, "AFF123", ts.referralAttachV1Code) + assert.Empty(t, ts.referralAttachV2Code) +} + +func TestReferralAttach_V1Error(t *testing.T) { + ac, ts := newTestClient(t) + ts.referralAttachV1Error = "invalid code" + resp, err := ac.ReferralAttach(context.Background(), "BAD", "") + require.Error(t, err) + assert.Nil(t, resp) + assert.Contains(t, err.Error(), "invalid code") +} + +func TestReferralAttach_ChannelUsesV2(t *testing.T) { + ac, ts := newTestClient(t) + resp, err := ac.ReferralAttach(context.Background(), "AFF123", "store") + require.NoError(t, err) + require.NotNil(t, resp) + assert.Equal(t, "AFF123", ts.referralAttachV2Code) + assert.Equal(t, "store", ts.referralAttachV2Channel) + assert.Empty(t, ts.referralAttachV1Code) + assert.Equal(t, "AFF123", resp.Code) + assert.Equal(t, 20, resp.DiscountPct) + assert.Equal(t, "affiliate", resp.Type) + assert.NotEmpty(t, resp.Plans) +} + +func TestReferralAttach_V2Error(t *testing.T) { + ac, ts := newTestClient(t) + ts.referralAttachV2Error = "invalid code" + resp, err := ac.ReferralAttach(context.Background(), "BAD", "store") + require.Error(t, err) + assert.Nil(t, resp) + assert.Contains(t, err.Error(), "invalid code") +} diff --git a/backend/radiance.go b/backend/radiance.go index 4f3466e4..c434dde3 100644 --- a/backend/radiance.go +++ b/backend/radiance.go @@ -1300,16 +1300,16 @@ func (r *LocalBackend) ActivationCode(ctx context.Context, email, resellerCode s return r.accountClient.ActivationCode(ctx, email, resellerCode) } -func (r *LocalBackend) NewStripeSubscription(ctx context.Context, email, planID string) (string, error) { - return r.accountClient.NewStripeSubscription(ctx, email, planID) +func (r *LocalBackend) NewStripeSubscription(ctx context.Context, email, planID, couponCode string) (string, error) { + return r.accountClient.NewStripeSubscription(ctx, email, planID, couponCode) } func (r *LocalBackend) PaymentRedirect(ctx context.Context, data account.PaymentRedirectData) (string, error) { return r.accountClient.PaymentRedirect(ctx, data) } -func (r *LocalBackend) ReferralAttach(ctx context.Context, code string) (bool, error) { - return r.accountClient.ReferralAttach(ctx, code) +func (r *LocalBackend) ReferralAttach(ctx context.Context, code, channel string) (*account.ReferralAttachResponse, error) { + return r.accountClient.ReferralAttach(ctx, code, channel) } func (r *LocalBackend) StripeBillingPortalURL(ctx context.Context) (string, error) { diff --git a/cmd/lantern/subscription.go b/cmd/lantern/subscription.go index efb047ed..f3776e42 100644 --- a/cmd/lantern/subscription.go +++ b/cmd/lantern/subscription.go @@ -29,8 +29,9 @@ type ActivateCmd struct { } type StripeSubCmd struct { - Email string `arg:"-e,--email" help:"email address"` - PlanID string `arg:"-p,--plan" help:"plan ID"` + Email string `arg:"-e,--email" help:"email address"` + PlanID string `arg:"-p,--plan" help:"plan ID"` + CouponCode string `arg:"-c,--coupon" help:"coupon code (optional)"` } type PaymentRedirectCmd struct { @@ -39,10 +40,12 @@ type PaymentRedirectCmd struct { Email string `arg:"-e,--email" help:"email address"` DeviceName string `arg:"-d,--device" help:"device name"` BillingType string `arg:"-b,--billing-type" default:"subscription" help:"one_time or subscription"` + CouponCode string `arg:"-c,--coupon" help:"coupon code (optional)"` } type ReferralCmd struct { - Code string `arg:"-c,--code" help:"referral code"` + Code string `arg:"-c,--code" help:"referral code"` + Channel string `arg:"--channel" help:"subscription channel (optional; when set, returns plans and discount)"` } type StripeBillingCmd struct{} @@ -129,7 +132,7 @@ func subStripeSub(ctx context.Context, c *ipc.Client, cmd *StripeSubCmd) error { return err } } - secret, err := c.NewStripeSubscription(ctx, email, planID) + secret, err := c.NewStripeSubscription(ctx, email, planID, cmd.CouponCode) if err != nil { return err } @@ -137,7 +140,7 @@ func subStripeSub(ctx context.Context, c *ipc.Client, cmd *StripeSubCmd) error { return nil } -func promptRedirectData(planID, provider, email, deviceName, billingType string) (account.PaymentRedirectData, error) { +func promptRedirectData(planID, provider, email, deviceName, billingType, couponCode string) (account.PaymentRedirectData, error) { var err error if planID == "" { planID, err = prompt("Plan ID: ") @@ -172,11 +175,12 @@ func promptRedirectData(planID, provider, email, deviceName, billingType string) Email: email, DeviceName: deviceName, BillingType: account.SubscriptionType(billingType), + CouponCode: couponCode, }, nil } func subRedirect(ctx context.Context, c *ipc.Client, cmd *PaymentRedirectCmd) error { - data, err := promptRedirectData(cmd.PlanID, cmd.Provider, cmd.Email, cmd.DeviceName, cmd.BillingType) + data, err := promptRedirectData(cmd.PlanID, cmd.Provider, cmd.Email, cmd.DeviceName, cmd.BillingType, cmd.CouponCode) if err != nil { return err } @@ -197,15 +201,15 @@ func subReferral(ctx context.Context, c *ipc.Client, cmd *ReferralCmd) error { return err } } - ok, err := c.ReferralAttach(ctx, code) + resp, err := c.ReferralAttach(ctx, code, cmd.Channel) if err != nil { return err } - if ok { - fmt.Println("Referral attached successfully") - } else { - fmt.Println("Referral was not attached") + out, err := json.MarshalIndent(resp, "", " ") + if err != nil { + return err } + fmt.Println(string(out)) return nil } diff --git a/ipc/client.go b/ipc/client.go index 193a3f52..518b13df 100644 --- a/ipc/client.go +++ b/ipc/client.go @@ -597,18 +597,22 @@ func (c *Client) ActivationCode(ctx context.Context, email, resellerCode string) } // NewStripeSubscription creates a new Stripe subscription and returns the client secret. -func (c *Client) NewStripeSubscription(ctx context.Context, email, planID string) (string, error) { +func (c *Client) NewStripeSubscription(ctx context.Context, email, planID, couponCode string) (string, error) { var resp ClientSecretResponse err := c.doJSON(ctx, http.MethodPost, subscriptionStripeEndpoint, - StripeSubscriptionRequest{Email: email, PlanID: planID}, &resp) + StripeSubscriptionRequest{Email: email, PlanID: planID, CouponCode: couponCode}, &resp) return resp.ClientSecret, err } -// ReferralAttach attaches a referral code to the current user. -func (c *Client) ReferralAttach(ctx context.Context, code string) (bool, error) { - var resp SuccessResponse - err := c.doJSON(ctx, http.MethodPost, subscriptionReferralEndpoint, CodeRequest{Code: code}, &resp) - return resp.Success, err +// ReferralAttach attaches a referral code to the current user. A non-empty +// channel also returns the resulting plans, providers, and discount. +func (c *Client) ReferralAttach(ctx context.Context, code, channel string) (*account.ReferralAttachResponse, error) { + var resp account.ReferralAttachResponse + err := c.doJSON(ctx, http.MethodPost, subscriptionReferralEndpoint, CodeRequest{Code: code, Channel: channel}, &resp) + if err != nil { + return nil, err + } + return &resp, nil } // StripeBillingPortalURL returns the Stripe billing portal URL. diff --git a/ipc/server.go b/ipc/server.go index 5defea38..dcb28da6 100644 --- a/ipc/server.go +++ b/ipc/server.go @@ -1082,7 +1082,7 @@ func (s *localapi) subscriptionStripeHandler(w http.ResponseWriter, r *http.Requ http.Error(w, err.Error(), http.StatusBadRequest) return } - clientSecret, err := s.backend(r.Context()).NewStripeSubscription(r.Context(), req.Email, req.PlanID) + clientSecret, err := s.backend(r.Context()).NewStripeSubscription(r.Context(), req.Email, req.PlanID, req.CouponCode) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -1110,12 +1110,12 @@ func (s *localapi) subscriptionReferralHandler(w http.ResponseWriter, r *http.Re http.Error(w, err.Error(), http.StatusBadRequest) return } - ok, err := s.backend(r.Context()).ReferralAttach(r.Context(), req.Code) + resp, err := s.backend(r.Context()).ReferralAttach(r.Context(), req.Code, req.Channel) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - writeJSON(w, http.StatusOK, SuccessResponse{Success: ok}) + writeJSON(w, http.StatusOK, resp) } func (s *localapi) subscriptionBillingPortalHandler(w http.ResponseWriter, r *http.Request) { diff --git a/ipc/types.go b/ipc/types.go index f9072d15..88f215ad 100644 --- a/ipc/types.go +++ b/ipc/types.go @@ -33,7 +33,8 @@ type OAuthTokenRequest struct { } type CodeRequest struct { - Code string `json:"code"` + Code string `json:"code"` + Channel string `json:"channel"` } type JSONConfigRequest struct { @@ -92,8 +93,9 @@ type ActivationRequest struct { } type StripeSubscriptionRequest struct { - Email string `json:"email"` - PlanID string `json:"planID"` + Email string `json:"email"` + PlanID string `json:"planID"` + CouponCode string `json:"couponCode"` } type VerifySubscriptionRequest struct { diff --git a/justfile b/justfile index c583ab8c..3af99a42 100644 --- a/justfile +++ b/justfile @@ -31,8 +31,8 @@ install: install-daemon install-cli proto: go build -o build/protoc-gen-go google.golang.org/protobuf/cmd/protoc-gen-go - protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative api/protos/auth.proto - protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative api/protos/subscription.proto + protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative account/protos/auth.proto + protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative account/protos/subscription.proto protoc --go_out=. --plugin=build/protoc-gen-go --go_opt=paths=source_relative issue/issue.proto test: