Skip to content

Auth

LaunchSwift’s auth flow is selected by AppConfig.deploymentPath through AuthServiceFactory.

  • ios/SwiftLaunch/Features/Auth/AuthState.swift@Observable auth state
  • ios/SwiftLaunch/Features/Auth/Models/AuthModels.swiftUser, AuthProvider, AuthError
  • ios/SwiftLaunch/Features/Auth/Services/AuthService.swift — service protocol + factory
  • ios/SwiftLaunch/Features/Auth/Services/AppleAuthService.swift — Sign in with Apple service
  • ios/SwiftLaunch/Features/Auth/Services/BackendAuthService.swift — backend auth API service
  • ios/SwiftLaunch/Features/Auth/Views/LoginView.swift — sign-in UI
  • ios/SwiftLaunch/Features/Auth/Views/SignUpView.swift — sign-up UI
@MainActor
@Observable
final class AuthState {
var currentUser: User?
var isLoading = false
var error: AuthError?
var isSignedIn: Bool { currentUser != nil }
func signIn() async
func signInWithEmail(email: String, password: String) async
func signUp(name: String, email: String, password: String) async
func checkSession() async
func signOut() async
}
enum AuthProvider: String, Codable, Sendable {
case apple
case backend
}
struct User: Codable, Equatable, Sendable {
let id: String
let email: String
let name: String
let authProvider: AuthProvider
}

AppleAuthService:

  • requests credentials via ASAuthorizationController
  • checks that identityToken and authorizationCode are present before saving a session
  • does not independently decode/verify token or code contents in the current implementation
  • saves session in Keychain (auth.apple.session)
  • validates existing sessions with ASAuthorizationAppleIDProvider.credentialState(forUserID:)

LoginView triggers AuthState.signIn() when email auth is disabled.

  • backend/src/auth.ts
  • backend/src/routes/auth.ts
  • backend/src/middleware/auth.ts

backend/src/index.ts mounts authRoutes under /api, so these are the effective paths:

MethodPathDescription
POST/api/auth/sign-in/appleApple sign-in using identity token
POST/api/auth/sign-in/emailEmail/password sign-in (handled via /auth/* better-auth handler)
POST/api/auth/sign-up/emailEmail/password sign-up (handled via /auth/* better-auth handler)
GET/api/auth/sessionResolve active session
POST/api/auth/sign-outSign out
GET/POST/PUT/PATCH/DELETE/OPTIONS/api/auth/*better-auth catch-all handler
  • D1 + Drizzle adapter when DB is available, memory adapter fallback otherwise
  • emailAndPassword.enabled = true
  • Apple social provider only when APPLE_CLIENT_ID and APPLE_CLIENT_SECRET are configured
  • Bearer plugin enabled (plugins: [bearer()])
  • basePath: "/api/auth"
Terminal window
# Required
BETTER_AUTH_SECRET=...
BETTER_AUTH_URL=https://your-worker.workers.dev
# Optional (enables Apple social auth)
APPLE_CLIENT_ID=...
APPLE_CLIENT_SECRET=...