Public
Likestudiokare-auth
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.
Viewing readonly version of main branch: v16View latest version
A single-tenant passwordless magic-link auth library for Deno + Hono + Val Town SQLite, with optional multi-client OAuth2 authorization code flow.
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);
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);
| Method | Path | Description |
|---|---|---|
POST | /magic-link | Request a magic link. Body: { "email": "..." } |
GET | /magic-link/:token | Verify magic link and create session |
POST | /logout | Destroy current session |
GET | /me | Return current user or null |
POST | /change-email | Request email change. Body: { "email": "..." } |
GET | /change-email/:token | Confirm email change |
Only available when oauth is configured. Implements the OAuth2 authorization code flow with stateless JWT access tokens.
| Method | Path | Description |
|---|---|---|
GET | /authorize | Start authorization flow. Query: response_type=code&client_id=...&redirect_uri=...&state=... |
POST | /authorize | User consents; generates auth code and redirects to redirect_uri |
POST | /token | Exchange auth code for JWT. Form: grant_type=authorization_code&code=...&redirect_uri=...&client_id=...&client_secret=... |
GET | /userinfo | Get user info from JWT. Header: Authorization: Bearer {jwt} |
POST | /users | Register a user (client-authenticated). Header: Authorization: Basic base64(client_id:client_secret). Body: { "email": "..." } |
- Client redirects user to
/oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=... - User authenticates via magic link (if not already logged in)
- User sees consent page and authorizes
- Auth server redirects to
redirect_uri?code=...&state=... - Client exchanges code for JWT at
POST /oauth/token - Client uses JWT at
GET /oauth/userinfo
{ "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600 }
{ "sub": "user-id", "email": "user@example.com" }
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
};
}
Used by ScalewayEmailService in backend/email.ts to send transactional emails (magic links, invites, email change confirmations).
| Variable | Required | Description |
|---|---|---|
SCW_REGION | Yes | Scaleway region (used to build the API endpoint) |
SCW_API_URL | Yes | Scaleway API base URL |
SCW_SECRET_KEY | Yes | Scaleway authentication secret |
SCW_PROJECT_ID | Yes | Scaleway project identifier |
SCW_FROM_EMAIL | Yes | Sender email address for transactional emails |
SCW_FROM_NAME | No | Sender 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.