• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
cricks_unmixed4u

cricks_unmixed4u

studiokare-auth

Reusable magic-link email auth for Val Town apps
Public
Like
studiokare-auth
Home
Code
6
.claude
1
.vscode
1
backend
11
frontend
2
README.md
types.ts
Environment variables
8
Branches
2
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version of main branch: v15
View latest version
README.md

studiokare-auth

A single-tenant passwordless magic-link auth library for Deno + Hono + Val Town SQLite, with optional multi-client OAuth2 authorization code flow.

Quick Start

import { createAuthApp } from "./backend/index.ts"; const { authApp, authMiddleware, runAuthMigrations } = createAuthApp({ appName: "MyApp", }); await runAuthMigrations(); const app = new Hono(); app.use("*", authMiddleware); app.route("/auth", authApp);

With OAuth2

const { authApp, oauthApp, authMiddleware, runAuthMigrations } = createAuthApp({ appName: "MyApp", oauth: { clients: [ { clientId: "my-client", clientSecret: "a-strong-secret", redirectUris: ["https://my-client-app.com/callback"], name: "My Client App", }, ], jwtSecret: "a-32-byte-or-longer-secret-key!!", // HMAC-SHA256 }, }); await runAuthMigrations(); const app = new Hono(); app.use("*", authMiddleware); app.route("/auth", authApp); if (oauthApp) app.route("/oauth", oauthApp);

Auth Endpoints (/auth)

MethodPathDescription
POST/magic-linkRequest a magic link. Body: { "email": "..." }
GET/magic-link/:tokenVerify magic link and create session
POST/logoutDestroy current session
GET/meReturn current user or null
POST/change-emailRequest email change. Body: { "email": "..." }
GET/change-email/:tokenConfirm email change

OAuth2 Endpoints (/oauth)

Only available when oauth is configured. Implements the OAuth2 authorization code flow with stateless JWT access tokens.

MethodPathDescription
GET/authorizeStart authorization flow. Query: response_type=code&client_id=...&redirect_uri=...&state=...
POST/authorizeUser consents; generates auth code and redirects to redirect_uri
POST/tokenExchange auth code for JWT. Form: grant_type=authorization_code&code=...&redirect_uri=...&client_id=...&client_secret=...
GET/userinfoGet user info from JWT. Header: Authorization: Bearer {jwt}
POST/usersRegister a user (client-authenticated). Header: Authorization: Basic base64(client_id:client_secret). Body: { "email": "..." }

OAuth2 Flow

  1. Client redirects user to /oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=...
  2. User authenticates via magic link (if not already logged in)
  3. User sees consent page and authorizes
  4. Auth server redirects to redirect_uri?code=...&state=...
  5. Client exchanges code for JWT at POST /oauth/token
  6. Client uses JWT at GET /oauth/userinfo

Token Response

{ "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600 }

Userinfo Response

{ "sub": "user-id", "email": "user@example.com" }

Configuration

interface AuthConfig { appName: string; tablePrefix?: string; // default: "studiokare" cookieName?: string; // default: "studiokare_session" sessionLifetimeMs?: number; // default: 30 days magicLinkTtlMs?: number; // default: 15 minutes emailService?: EmailService; emailTemplates?: { ... }; oauth?: { clients: OAuthClient[]; jwtSecret: string; // HMAC-SHA256 key (>= 32 bytes) accessTokenTtlMs?: number; // default: 1 hour authCodeTtlMs?: number; // default: 10 minutes }; }

Environment Variables

Scaleway Email Service

Used by ScalewayEmailService in backend/email.ts to send transactional emails (magic links, invites, email change confirmations).

VariableRequiredDescription
SCW_REGIONYesScaleway region (used to build the API endpoint)
SCW_API_URLYesScaleway API base URL
SCW_SECRET_KEYYesScaleway authentication secret
SCW_PROJECT_IDYesScaleway project identifier
SCW_FROM_EMAILYesSender email address for transactional emails
SCW_FROM_NAMENoSender display name (optional)

If SCW_SECRET_KEY and SCW_PROJECT_ID are not set, the system falls back to ConsoleEmailService, which logs emails to the console instead of sending them.

FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.