Skip to content

feat: Google OAuth, multi-group home page, branding, and guest join#19

Merged
pkmaster21 merged 3 commits intomainfrom
feature/google-auth-and-multi-group
Apr 16, 2026
Merged

feat: Google OAuth, multi-group home page, branding, and guest join#19
pkmaster21 merged 3 commits intomainfrom
feature/google-auth-and-multi-group

Conversation

@pkmaster21
Copy link
Copy Markdown
Owner

@pkmaster21 pkmaster21 commented Apr 12, 2026

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 User record and creates a Session with a hashed token in an httpOnly cookie. A dual-path session middleware resolves both new authenticated sessions (via the sessions table) and existing anonymous sessions (via members.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 initialExpense prop 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 styled ConfirmDialog modal component.

Branding

  • TabbyLogo — SVG tabby cat holding a receipt, used in headers and the login page
  • CatBackground — faint cat face silhouette tiled background pattern
  • "Keep your tabs in check." tagline on login and landing pages
  • Clickable logo + back button navigation on dashboard and settings pages

Infrastructure

  • users, sessions tables added to the schema; members.userId (nullable FK) and nullable sessionToken
  • Google OAuth credentials (GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI) added to SSM Parameter Store via Terraform
  • GET /me/groups, GET /groups/:id/me, POST /auth/* endpoints
  • Test-only POST /auth/test-login endpoint (dev/test only) for E2E tests

Docs

Updated design-spec.md, README.md, TODO.md, and split future work into FUTURE.md.

🤖 Generated with Claude Code

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
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 12, 2026

Deploying tabby with  Cloudflare Pages  Cloudflare Pages

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

View logs

@pkmaster21 pkmaster21 force-pushed the feature/google-auth-and-multi-group branch 6 times, most recently from c45b818 to 5a5f53e Compare April 12, 2026 18:34
Plan has been fully executed; keeping it as a file adds noise.
History is preserved in git if needed later.
@pkmaster21 pkmaster21 force-pushed the feature/google-auth-and-multi-group branch from 5a5f53e to 01bf5e2 Compare April 15, 2026 23:54
- 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
@pkmaster21 pkmaster21 merged commit 05dd67e into main Apr 16, 2026
7 checks passed
@pkmaster21 pkmaster21 deleted the feature/google-auth-and-multi-group branch April 16, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant