feat: Google OAuth, multi-group home page, branding, and guest join#19
Merged
pkmaster21 merged 3 commits intomainfrom Apr 16, 2026
Merged
feat: Google OAuth, multi-group home page, branding, and guest join#19pkmaster21 merged 3 commits intomainfrom
pkmaster21 merged 3 commits intomainfrom
Conversation
Adds Google OAuth authentication so users have persistent identity across devices, with a home page listing all their groups. Invite links now support guest joins (no account required) using the existing anonymous session path as a fallback. Also ships edit expense UI, styled confirmation dialogs, the Tabby cat logo and background pattern, and back-navigation on all pages. Key changes: - Google OAuth flow (authorization code, CSRF state, session table) - Dual-path session resolution: new sessions table + legacy membertoken fallback - GET /me/groups and GET /groups/:id/me endpoints - Guest join via invite link creates an anonymous member session - Home page shows group list when signed in, landing page when not - Edit expense modal (pre-populated fields, save changes flow) - ConfirmDialog component replaces all browser confirm() calls - TabbyLogo SVG component and CatBackground pattern - Navigation: clickable logo + back button on dashboard and settings - myGroups query invalidated after create/join - Test-only POST /auth/test-login bypass for E2E tests - Smoke tests updated for auth flow and guest join
Deploying tabby with
|
| Latest commit: |
f9cb5d5
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://1857697c.tabby.pages.dev |
| Branch Preview URL: | https://feature-google-auth-and-mult.tabby.pages.dev |
c45b818 to
5a5f53e
Compare
Plan has been fully executed; keeping it as a file adds noise. History is preserved in git if needed later.
5a5f53e to
01bf5e2
Compare
- Remove duplicate role === 'owner' check in DashboardPage that caused TS narrowing error - Drop unused ProtectedRoute import in App.tsx - Fix guest-merge test assertion to check leftAt is set rather than expecting undefined
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.
What this does
Tabby previously had no authentication — each group used an anonymous browser session. This PR adds Google OAuth so users have persistent identity across devices, along with several features that depend on it.
Authentication
Sign in with Google via the standard OAuth 2.0 authorization code flow. The server upserts a
Userrecord and creates aSessionwith a hashed token in an httpOnly cookie. A dual-path session middleware resolves both new authenticated sessions (via thesessionstable) and existing anonymous sessions (viamembers.sessionToken), so no existing data is broken.Guest group creation
Group owners can now create a group without signing in, using the same guest session pattern as invite-link joiners. The create page is no longer behind an auth guard — unauthenticated users land there directly from the home page, enter a name, and get a cookie-backed session. A nudge on the form links them to sign in with Google for cross-device persistence.
When a guest owner later signs in with Google, the OAuth callback detects the guest cookie and links all their guest member records to the Google account. If the Google user was already a member of a group (e.g. joined via a different path), the guest record is soft-deleted instead to avoid conflicts.
Guest join via invite link
Visitors can enter a name and join a group without a Google account. The backend generates an anonymous member session token for them, so they land directly on the dashboard and can add expenses. A small nudge on the join page links them to sign in for cross-device access.
Multi-group home page
The landing page now shows "Create a group" as the primary CTA alongside "Sign in with Google", so unauthenticated users can get started immediately. Authenticated users see a list of all their groups with member count and role badge.
Edit expense UI
The add expense modal now accepts an
initialExpenseprop for edit mode. A pencil icon appears next to each expense the current user can edit (own expenses, or any expense if admin/owner).Confirmation dialogs
All three
confirm()calls (delete expense, remove member, regenerate invite link) are replaced with a styledConfirmDialogmodal component.Branding
TabbyLogo— SVG tabby cat holding a receipt, used in headers and the login pageCatBackground— faint cat face silhouette tiled background patternInfrastructure
users,sessionstables added to the schema;members.userId(nullable FK) and nullablesessionTokenGOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_REDIRECT_URI) added to SSM Parameter Store via TerraformGET /me/groups,GET /groups/:id/me,POST /auth/*endpointsPOST /auth/test-loginendpoint (dev/test only) for E2E testsDocs
Updated
design-spec.md,README.md,TODO.md, and split future work intoFUTURE.md.🤖 Generated with Claude Code