feat(auth): migrate onto @aswincloud/auth, access policy gate, central OAuth broker - #13
Merged
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
shiptrack | 9eeaff0 | Aug 14 2026, 09:58 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
shiptrack-poller | 9eeaff0 | Aug 14 2026, 09:58 AM |
Aswincloud-Bot
approved these changes
Aug 14, 2026
Aswincloud-Bot
left a comment
There was a problem hiding this comment.
Auto-approved: @Aswinmcw is a member of @Aswincloud/admins.
…Auth) Make the published package the single source of truth for auth. Delete the duplicated primitives (lib/passwords, lib/otp, lib/oauth) and rewrite the auth route handlers onto the package's /d1 flows (signup, verifyOtp, resendOtp, requestPasswordReset, resetPassword, changePassword, changeUsername, requestEmailChange, confirmEmailChange, removeUser) plus core startOAuth/ handleOAuthCallback. A small lib/authpkg.ts bridges our AppEnv → OAuthConfig and wraps our Resend sendEmail as the package's EmailSender; ShipTrack-branded auth emails are preserved via the new render* template overrides (pkg 0.3.0). Session/OAuth cookie names (shiptrack_session, shiptrack_oauth_state) and the token/hash formats are unchanged, so existing sessions and stored password hashes stay valid. lib/auth.ts stays as the thin Next adapter (next/headers, requireAdmin); lib/tokens.ts and lib/email.ts stay for watches + the poller. Email change switches from admin-approval to the package's self-service, token-verified flow: new /confirm-email page + /api/auth/confirm-email route; removed the admin review queue (routes, db functions, dashboard UI) and the settings pending-request panel. The email_change_requests table is left in place (no destructive migration); it's simply no longer read or written. Verified: tsc clean, opennextjs-cloudflare build OK, and a local D1 smoke run (14 checks) covering signup/verify, login (+unverified), forgot/reset, change-password, change-name, self-service email change, last-admin delete guard, removed admin routes 404, and the regression that an existing session cookie + stored hash still authenticate, plus watch unsubscribe links intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a per-site access policy that gates *account creation* only — existing users (password or returning OAuth identity) are never re-gated: - lib/authpkg.ts: emailAllowedForSite(env,email). Unlike the package default (fail-closed to 'owners'), shiptrack fails OPEN to 'public' when ACCESS_MODE is unset, preserving historical open signup. ACCESS_MODE=domain (+ACCESS_DOMAINS) or =owners (+OWNER_EMAILS) restrict it. - signup route: 403 not_allowed before any DB read (no account-existence leak). - OAuth callback: gate only the brand-new-user branch; returning/link flows unchanged. New disallowed email → /login?oauth_error=not_allowed. - env.ts: ACCESS_MODE / ACCESS_DOMAINS / OWNER_EMAILS. Bumps @aswincloud/auth to ^0.4.0. Password/email-change/watch flows untouched.
…-id linking) When AUTH_BROKER_URL + RELAY_SECRET are set, OAuth goes through the broker (one client per provider, shared across sites) instead of shiptrack's own provider clients; falls back to the local clients when unset. - authpkg.ts: brokerConfigured / brokerStart (302 + signed nonce cookie) / verifyBrokerRelay (relay sig + provider + nonce match) / clearBrokerNonceCookie. - start route: broker 302 when configured, else local startOAuth. - callback: broker path reads ?relay, verifyBrokerRelay, then the SAME account-linking as before — now keyed on claims.providerUserId (relayed by the broker since pkg 0.5.0), so links stay on (provider, provider_user_id), no email-only downgrade. Linking extracted into a shared loginWithIdentity(). - providers route: proxies the broker's per-site list (id-only shape kept). - env.ts: AUTH_BROKER_URL, RELAY_SECRET. Bumps @aswincloud/auth to ^0.5.0. Password/OTP/email-change/watch flows untouched. Registered shiptrack with the broker for [google,github,microsoft]; only Google is configured on the broker today, so the login page shows Google until the other apps are added (then they appear automatically).
Aswinmcw
force-pushed
the
feat/auth-broker-migration
branch
from
August 14, 2026 10:08
9eeaff0 to
b7ad19a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The three commits that were sitting unpushed on local
main. Rebased onto currentmain(clean — no conflicts with the dependabot bumps).What's here
feat(auth): migrate onto @aswincloud/auth— moves session/OAuth/password primitives and the/d1flows (signup, login, OTP, reset, email change, account delete) onto the shared package.src/lib/oauth.ts,otp.ts,passwords.tsare dropped;src/lib/authpkg.tsis the new bridge to our env + Resend transport. Cookie names and token format are unchanged, so existing sessions and in-flight OAuth round-trips survive the swap.feat: access-policy gate on account creation—ACCESS_MODE/ACCESS_DOMAINS/OWNER_EMAILSgate account creation only; existing users are never re-gated. Unset ⇒public, preserving current open signup.feat: route OAuth sign-in through the central broker— whenAUTH_BROKER_URL+RELAY_SECRETare set, sign-in relays through auth.aswincloud.com (one OAuth client per provider, shared across sites) instead of per-site clients. Nonce-bound, and linking still runs on the provider's stable user id. Falls back to the local clients when the broker isn't configured.Notes
tsc --noEmitpasses.email_change_requeststable is no longer read or written. The table is left in place — no destructive migration..env.examplestill documents only the original five vars and is missing every OAuth / broker / access-policy var. Worth a separate docs pass along with the README, which still describes alerts as owner-only.