44406b72db
Moteva-style AI design workbench replica. Home prompt creates a project; the project page provides an infinite canvas with node drag, zoom/pan, a design chat panel, history replay, image asset upload, and project save/regenerate. - Backend: go-zero, DDD layering, sqlc/pgx, optional PostgreSQL; memory or Redis cache; asynq job queue; MinIO/S3/R2/OSS object storage; sky-valley/pi agent runtime adapter. - Frontend: Next.js App Router + Vite artifact build, TypeScript, i18n, shadcn/ui components, auth (OTP/Turnstile/Google/WeChat). - Deploy: Docker Compose and k3s manifests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
101 lines
2.7 KiB
Go
101 lines
2.7 KiB
Go
package logic
|
|
|
|
import (
|
|
authmodule "img_infinite_canvas/internal/modules/auth"
|
|
"img_infinite_canvas/internal/types"
|
|
)
|
|
|
|
func toAPIAuthOptions(options authmodule.Options) *types.AuthOptionsResponse {
|
|
methods := make([]types.AuthMethod, 0, len(options.Methods))
|
|
for _, method := range options.Methods {
|
|
methods = append(methods, types.AuthMethod{
|
|
Id: method.ID,
|
|
Label: method.Label,
|
|
Provider: method.Provider,
|
|
})
|
|
}
|
|
return &types.AuthOptionsResponse{
|
|
Region: options.Region,
|
|
Methods: methods,
|
|
Turnstile: types.AuthTurnstileOptions{
|
|
Enabled: options.Turnstile.Enabled,
|
|
SiteKey: options.Turnstile.SiteKey,
|
|
},
|
|
}
|
|
}
|
|
|
|
func toAPIAuthCode(result authmodule.CodeResult) *types.AuthCodeResponse {
|
|
var email *types.AuthEmailMessage
|
|
if result.Email != nil {
|
|
email = &types.AuthEmailMessage{
|
|
FromName: result.Email.FromName,
|
|
FromEmail: result.Email.FromEmail,
|
|
ToEmail: result.Email.ToEmail,
|
|
Subject: result.Email.Subject,
|
|
Code: result.Email.Code,
|
|
Text: result.Email.Text,
|
|
Html: result.Email.HTML,
|
|
}
|
|
}
|
|
return &types.AuthCodeResponse{
|
|
Target: result.Target,
|
|
ExpiresIn: result.ExpiresIn,
|
|
DevCode: result.DevCode,
|
|
Email: email,
|
|
}
|
|
}
|
|
|
|
func toAPIAuthSession(session authmodule.Session) *types.AuthSessionResponse {
|
|
status := session.Status
|
|
if status == "" {
|
|
status = authmodule.SessionStatusAuthenticated
|
|
}
|
|
return &types.AuthSessionResponse{
|
|
Status: status,
|
|
User: types.AuthUser{
|
|
Id: session.User.ID,
|
|
Region: session.User.Region,
|
|
Phone: session.User.Phone,
|
|
CountryCode: session.User.CountryCode,
|
|
Email: session.User.Email,
|
|
Name: session.User.Name,
|
|
AvatarUrl: session.User.AvatarURL,
|
|
},
|
|
AccessToken: session.AccessToken,
|
|
ExpiresIn: session.ExpiresIn,
|
|
RefreshToken: session.RefreshToken,
|
|
RefreshExpiresIn: session.RefreshExpiresIn,
|
|
BindingToken: session.BindingToken,
|
|
BindingExpiresIn: session.BindingExpiresIn,
|
|
}
|
|
}
|
|
|
|
func toAPIAuthUser(user authmodule.User) types.AuthUser {
|
|
return types.AuthUser{
|
|
Id: user.ID,
|
|
Region: user.Region,
|
|
Phone: user.Phone,
|
|
CountryCode: user.CountryCode,
|
|
Email: user.Email,
|
|
Name: user.Name,
|
|
AvatarUrl: user.AvatarURL,
|
|
}
|
|
}
|
|
|
|
func toAPIAccountDevices(devices []authmodule.Device) []types.AccountDevice {
|
|
items := make([]types.AccountDevice, 0, len(devices))
|
|
for _, device := range devices {
|
|
items = append(items, types.AccountDevice{
|
|
Id: device.ID,
|
|
Online: device.Online,
|
|
Current: device.Current,
|
|
DeviceType: device.DeviceType,
|
|
System: device.System,
|
|
Browser: device.Browser,
|
|
Client: device.Client,
|
|
LastSeenAt: device.LastSeenAt.UTC().Format("2006-01-02 15:04(UTC)"),
|
|
})
|
|
}
|
|
return items
|
|
}
|