Stage 11: account linking & merge (email + Telegram Login Widget) (#12)
Tests · Go / test (push) Successful in 7s
Tests · Integration / integration (push) Successful in 11s
Tests · UI / test (push) Successful in 18s

This commit was merged in pull request #12.
This commit is contained in:
2026-06-04 09:18:17 +00:00
parent 3a640a17a4
commit 01485d8fc6
68 changed files with 3331 additions and 369 deletions
+50 -4
View File
@@ -30,10 +30,11 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
Telegram_ValidateInitData_FullMethodName = "/scrabble.telegram.v1.Telegram/ValidateInitData"
Telegram_Notify_FullMethodName = "/scrabble.telegram.v1.Telegram/Notify"
Telegram_SendToUser_FullMethodName = "/scrabble.telegram.v1.Telegram/SendToUser"
Telegram_SendToGameChannel_FullMethodName = "/scrabble.telegram.v1.Telegram/SendToGameChannel"
Telegram_ValidateInitData_FullMethodName = "/scrabble.telegram.v1.Telegram/ValidateInitData"
Telegram_ValidateLoginWidget_FullMethodName = "/scrabble.telegram.v1.Telegram/ValidateLoginWidget"
Telegram_Notify_FullMethodName = "/scrabble.telegram.v1.Telegram/Notify"
Telegram_SendToUser_FullMethodName = "/scrabble.telegram.v1.Telegram/SendToUser"
Telegram_SendToGameChannel_FullMethodName = "/scrabble.telegram.v1.Telegram/SendToGameChannel"
)
// TelegramClient is the client API for Telegram service.
@@ -46,6 +47,11 @@ type TelegramClient interface {
// the authenticated user. The gateway calls it during the auth.telegram edge
// operation, then provisions the session through the backend internal API.
ValidateInitData(ctx context.Context, in *ValidateInitDataRequest, opts ...grpc.CallOption) (*ValidateInitDataResponse, error)
// ValidateLoginWidget verifies Telegram Login Widget authorization data (the web
// sign-in flow, HMAC under SHA-256(bot_token)) and returns the authenticated
// user. The gateway calls it during the link.telegram edge operation to attach a
// Telegram identity to an existing account (Stage 11).
ValidateLoginWidget(ctx context.Context, in *ValidateLoginWidgetRequest, opts ...grpc.CallOption) (*ValidateLoginWidgetResponse, error)
// Notify delivers an out-of-app notification for a backend push event. The
// gateway calls it only for a recipient with no live in-app stream (so the
// platform push never duplicates in-app delivery). The connector renders a
@@ -79,6 +85,16 @@ func (c *telegramClient) ValidateInitData(ctx context.Context, in *ValidateInitD
return out, nil
}
func (c *telegramClient) ValidateLoginWidget(ctx context.Context, in *ValidateLoginWidgetRequest, opts ...grpc.CallOption) (*ValidateLoginWidgetResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ValidateLoginWidgetResponse)
err := c.cc.Invoke(ctx, Telegram_ValidateLoginWidget_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *telegramClient) Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(NotifyResponse)
@@ -119,6 +135,11 @@ type TelegramServer interface {
// the authenticated user. The gateway calls it during the auth.telegram edge
// operation, then provisions the session through the backend internal API.
ValidateInitData(context.Context, *ValidateInitDataRequest) (*ValidateInitDataResponse, error)
// ValidateLoginWidget verifies Telegram Login Widget authorization data (the web
// sign-in flow, HMAC under SHA-256(bot_token)) and returns the authenticated
// user. The gateway calls it during the link.telegram edge operation to attach a
// Telegram identity to an existing account (Stage 11).
ValidateLoginWidget(context.Context, *ValidateLoginWidgetRequest) (*ValidateLoginWidgetResponse, error)
// Notify delivers an out-of-app notification for a backend push event. The
// gateway calls it only for a recipient with no live in-app stream (so the
// platform push never duplicates in-app delivery). The connector renders a
@@ -145,6 +166,9 @@ type UnimplementedTelegramServer struct{}
func (UnimplementedTelegramServer) ValidateInitData(context.Context, *ValidateInitDataRequest) (*ValidateInitDataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ValidateInitData not implemented")
}
func (UnimplementedTelegramServer) ValidateLoginWidget(context.Context, *ValidateLoginWidgetRequest) (*ValidateLoginWidgetResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ValidateLoginWidget not implemented")
}
func (UnimplementedTelegramServer) Notify(context.Context, *NotifyRequest) (*NotifyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Notify not implemented")
}
@@ -193,6 +217,24 @@ func _Telegram_ValidateInitData_Handler(srv interface{}, ctx context.Context, de
return interceptor(ctx, in, info, handler)
}
func _Telegram_ValidateLoginWidget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ValidateLoginWidgetRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TelegramServer).ValidateLoginWidget(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Telegram_ValidateLoginWidget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TelegramServer).ValidateLoginWidget(ctx, req.(*ValidateLoginWidgetRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Telegram_Notify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NotifyRequest)
if err := dec(in); err != nil {
@@ -258,6 +300,10 @@ var Telegram_ServiceDesc = grpc.ServiceDesc{
MethodName: "ValidateInitData",
Handler: _Telegram_ValidateInitData_Handler,
},
{
MethodName: "ValidateLoginWidget",
Handler: _Telegram_ValidateLoginWidget_Handler,
},
{
MethodName: "Notify",
Handler: _Telegram_Notify_Handler,