also looking at this
Deploy: GitHub sign-in credentials, auth helper move, callback defaults
#9
10 files
+15
-12
| @@ -97,4 +97,7 @@ QUEUE_WORKER_CONCURRENCY="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBV | ||
| 97 | 97 | # Reports this app's own errors to bughq (project: loghq). |
| 98 | 98 | BUGHQ_KEY="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBQ212TlNiUnNvcHNJa2plZlJSMUJ6bXRVVG5zWVNqVVpxenRJTTNGQXFDVSIsInNhbHQiOiJnaUNHWVJEZkc4WUJVc3pRNG9UQ2FRIiwibm9uY2UiOiJFS3BVNWZJakdrSzlPWXh1IiwiY2lwaGVydGV4dCI6ImxIc1J2OXRPUjZlTGRrSHJmYk11R0NIOTVUYVpKVklEXzFReFJTZjFZRWU2UExjeW83LTdMUEp3QzNFd210TTlkcFJsYm80eDlEdWkxeWgwVkJDYVZsLXAtblB6TXciLCJ0YWciOiJ6dVJQdjFXMGZrcVc4OF9UOXhkZU53In0" |
| 99 | 99 | |
| 100 | ANALYTICSHQ_APP_ID="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBZC1VY3h6RnZGYlJFamlPR3pzdXNoV0w2aUZJTV9HZWZSaG5HaXBnUDJDTSIsInNhbHQiOiJQa3cwYU5uRnptaks4YlpTYnRBMFJRIiwibm9uY2UiOiJmcXpzLU1jSzB6YTFFZzVTIiwiY2lwaGVydGV4dCI6IkZ0UXhoYUhzVlRzU1p3cExIX1JuZmpvWk85XzdDeG82IiwidGFnIjoiSzhjVHk2eHE1OEtwc0c4UDgyYjBqUSJ9"⧵ | |
| 100 | ANALYTICSHQ_APP_ID="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBZC1VY3h6RnZGYlJFamlPR3pzdXNoV0w2aUZJTV9HZWZSaG5HaXBnUDJDTSIsInNhbHQiOiJQa3cwYU5uRnptaks4YlpTYnRBMFJRIiwibm9uY2UiOiJmcXpzLU1jSzB6YTFFZzVTIiwiY2lwaGVydGV4dCI6IkZ0UXhoYUhzVlRzU1p3cExIX1JuZmpvWk85XzdDeG82IiwidGFnIjoiSzhjVHk2eHE1OEtwc0c4UDgyYjBqUSJ9" | |
| 101 | GITHUB_REDIRECT_URL="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBdFpORy1WcEtFU2pyUXI3dU9NamRMbW82enVlSVRpb0ZfZGxleWZGQlhIdyIsInNhbHQiOiJyZTljX3I3eXhIOWlUY0o0RGJwem5nIiwibm9uY2UiOiJOVk9CUmlnRldHd1BGVG15IiwiY2lwaGVydGV4dCI6InRNOE4zalluMktGVkFPSXd4WV9aSzdZTmhKSGt0YUcxQzVrVmJRRDBRcFRRSnkxVjhFd0kycHpMIiwidGFnIjoiX2V3Z1o1SHB5YWN2OFRFQUhMMEtxdyJ9" | |
| 102 | GITHUB_CLIENT_SECRET="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBMTE3aHZGVmlyX1dQNXFmOVRaMzVQNUh6Q2tzbnk4MFhPNG8tODQyRm5GcyIsInNhbHQiOiJHWGU2ZG96T2hTLWIzWjYxOUVrNnNRIiwibm9uY2UiOiJ3UkFrUTBXNFU1ODdGSUxoIiwiY2lwaGVydGV4dCI6IkN6MmJJdk5EU25TcHNpUDh6WWtTUzFqWUpFUXd5b1p3dlhTU3dmeW5LY2lhNDJkQV91RVBQdyIsInRhZyI6InR0bFd0aG01Zi1hcGwzUEZwbkt3cXcifQ" | |
| 103 | GITHUB_CLIENT_ID="encrypted:v2:eyJ2IjoyLCJlcGsiOiJNQ293QlFZREsyVnVBeUVBUHFrbDF5dVdvTktIWHAwWmd6VkwyOWthQlc1djM4RkJITUV2RmF4Y1loSSIsInNhbHQiOiJlM0xzTHR5Sm01WlVVZ3VzZGc1YkFRIiwibm9uY2UiOiJ5d2d5TWNld2lkdG9HdVN1IiwiY2lwaGVydGV4dCI6Ijk3cEF6N3ZlMFNOMDNoY05UdzhmTXpWbWNBOCIsInRhZyI6InpKSTdJdHp3aEREM0ZEekVsUFdFZHcifQ" | |
| @@ -4,7 +4,7 @@ import { Auth, createTwoFactorChallenge, getTwoFactorState } from '@stacksjs/aut | ||
| 4 | 4 | import { User } from '@stacksjs/orm' |
| 5 | 5 | import { response } from '@stacksjs/router' |
| 6 | 6 | import { schema } from '@stacksjs/validation' |
| 7 | import { buildAuthCookie, sessionExpiryMinutes } from './authCookie' | |
| 7 | import { buildAuthCookie, sessionExpiryMinutes } from '../../Support/authCookie' | |
| 8 | 8 | |
| 9 | 9 | /** |
| 10 | 10 | * Email/password sign-in, registered at POST /api/auth/login (routes/auth.ts). |
| @@ -2,7 +2,7 @@ import type { RequestInstance } from '@stacksjs/types' | ||
| 2 | 2 | import { Action } from '@stacksjs/actions' |
| 3 | 3 | import { Auth } from '@stacksjs/auth' |
| 4 | 4 | import { response } from '@stacksjs/router' |
| 5 | import { clearAuthCookie } from './authCookie' | |
| 5 | import { clearAuthCookie } from '../../Support/authCookie' | |
| 6 | 6 | |
| 7 | 7 | /** |
| 8 | 8 | * Project override of the framework's default LogoutAction — same token |
| @@ -3,7 +3,7 @@ import { Action } from '@stacksjs/actions' | ||
| 3 | 3 | import { Auth, register } from '@stacksjs/auth' |
| 4 | 4 | import { response } from '@stacksjs/router' |
| 5 | 5 | import { schema } from '@stacksjs/validation' |
| 6 | import { buildAuthCookie } from './authCookie' | |
| 6 | import { buildAuthCookie } from '../../Support/authCookie' | |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | 9 | * Account creation, registered at POST /api/auth/register (routes/auth.ts). |
| @@ -6,7 +6,7 @@ import { config } from '@stacksjs/config' | ||
| 6 | 6 | import { db } from '@stacksjs/database' |
| 7 | 7 | import { response } from '@stacksjs/router' |
| 8 | 8 | import { GitHubProvider, GoogleProvider } from '@stacksjs/socials' |
| 9 | import { buildAuthCookie, sessionExpiryMinutes } from './authCookie' | |
| 9 | import { buildAuthCookie, sessionExpiryMinutes } from '../../Support/authCookie' | |
| 10 | 10 | |
| 11 | 11 | function makeDriver(provider: string): GitHubProvider | GoogleProvider | null { |
| 12 | 12 | const svc = config.services as any |
| @@ -3,7 +3,7 @@ import { Action } from '@stacksjs/actions' | ||
| 3 | 3 | import { Auth, consumeTwoFactorChallenge, verifyTwoFactorLoginCode } from '@stacksjs/auth' |
| 4 | 4 | import { response } from '@stacksjs/router' |
| 5 | 5 | import { schema } from '@stacksjs/validation' |
| 6 | import { buildAuthCookie, sessionExpiryMinutes } from './authCookie' | |
| 6 | import { buildAuthCookie, sessionExpiryMinutes } from '../../Support/authCookie' | |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | 9 | * Exchange a LoginAction 2FA challenge + TOTP code for a real session, |
Renamed from app/Actions/Auth/authCookie.ts. The contents are unchanged.
| @@ -53,7 +53,7 @@ export default { | ||
| 53 | 53 | * The custom auth actions (LoginAction, RegisterAction, |
| 54 | 54 | * VerifyTwoFactorLoginAction, SocialCallbackAction) mirror the issued |
| 55 | 55 | * access token into the HttpOnly `auth-token` cookie (see |
| 56 | * Actions/Auth/authCookie.ts) because the dashboard is server-rendered stx | |
| 56 | * Support/authCookie.ts) because the dashboard is server-rendered stx | |
| 57 | 57 | * with no client hydration and has no other way to know who is asking. Both |
| 58 | 58 | * the cookie's Max-Age and the `oauth_access_tokens.expires_at` row are |
| 59 | 59 | * stamped from here, and nothing extends either one — `getUserFromToken` |
| @@ -63,7 +63,7 @@ export default { | ||
| 63 | 63 | * |
| 64 | 64 | * This is the BASELINE only. LoginAction and VerifyTwoFactorLoginAction |
| 65 | 65 | * pass a per-login `expiresInMinutes` from the sign-in form's "remember me" |
| 66 | * checkbox (see sessionExpiryMinutes in Actions/Auth/authCookie.ts): a week | |
| 66 | * checkbox (see sessionExpiryMinutes in Support/authCookie.ts): a week | |
| 67 | 67 | * unchecked, 30 days checked. This default covers the entry points that have |
| 68 | 68 | * no such checkbox — register, SSO — so they land on the baseline week. |
| 69 | 69 | */ |
| @@ -54,21 +54,21 @@ export default { | ||
| 54 | 54 | teamId: String(env.APPLE_TEAM_ID || ''), |
| 55 | 55 | keyId: String(env.APPLE_KEY_ID || ''), |
| 56 | 56 | privateKey: String(env.APPLE_PRIVATE_KEY || ''), // literal \n newlines allowed |
| 57 | redirectUrl: String(env.APPLE_REDIRECT_URL || 'http://localhost:3000/auth/apple/callback'), | |
| 57 | redirectUrl: String(env.APPLE_REDIRECT_URL || `${oauthBase()}/api/auth/apple/callback`), | |
| 58 | 58 | scopes: ['name', 'email'], |
| 59 | 59 | }, |
| 60 | 60 | |
| 61 | 61 | facebook: { |
| 62 | 62 | clientId: String(env.FACEBOOK_CLIENT_ID || ''), |
| 63 | 63 | clientSecret: String(env.FACEBOOK_CLIENT_SECRET || ''), |
| 64 | redirectUrl: String(env.FACEBOOK_REDIRECT_URL || 'http://localhost:3000/auth/facebook/callback'), | |
| 64 | redirectUrl: String(env.FACEBOOK_REDIRECT_URL || `${oauthBase()}/api/auth/facebook/callback`), | |
| 65 | 65 | scopes: ['email', 'public_profile'], |
| 66 | 66 | }, |
| 67 | 67 | |
| 68 | 68 | twitter: { |
| 69 | 69 | clientId: String(env.TWITTER_CLIENT_ID || ''), |
| 70 | 70 | clientSecret: String(env.TWITTER_CLIENT_SECRET || ''), |
| 71 | redirectUrl: String(env.TWITTER_REDIRECT_URL || 'http://localhost:3000/auth/twitter/callback'), | |
| 71 | redirectUrl: String(env.TWITTER_REDIRECT_URL || `${oauthBase()}/api/auth/twitter/callback`), | |
| 72 | 72 | scopes: ['tweet.read', 'users.read', 'offline.access'], |
| 73 | 73 | }, |
| 74 | 74 | |
| @@ -8,7 +8,7 @@ import { response, route } from '@stacksjs/router' | ||
| 8 | 8 | * prefix (config/server.ts). login.stx / register.stx are now client-fetch |
| 9 | 9 | * forms that POST here with `credentials: 'same-origin'`; on success each |
| 10 | 10 | * action returns a single HttpOnly `auth-token` cookie (see |
| 11 | * Actions/Auth/authCookie.ts) that IS the session — there is no localStorage | |
| 11 | * Support/authCookie.ts) that IS the session — there is no localStorage | |
| 12 | 12 | * token, no Authorization header and no refresh exchange anywhere. |
| 13 | 13 | * |
| 14 | 14 | * `.skipCsrf()` stays: the endpoints are same-origin fetches, and the cookie |