Skip to content

Feat/oauth endpoints - #56

Merged
Basharkhan7776 merged 3 commits into
Openlabsops:mainfrom
silky-x0:feat/Oauth-endpoints
Jun 23, 2026
Merged

Basharkhan7776 merged 3 commits into
Openlabsops:mainfrom
silky-x0:feat/Oauth-endpoints

Conversation

@silky-x0

@silky-x0 silky-x0 commented Jun 23, 2026 •

Copy link
Copy Markdown
Collaborator

What's Changed

This PR introduces OAuth authentication support using Google and GitHub via better-auth. It implements a redirect-based onboarding flow that directs new users to an onboarding screen, while returning users go straight to the dashboard.

Closes #49

Key Implementation Details

1. Database Schema Updates

  • CamelCase Migration: Renamed snake_case fields in the Account model to camelCase (refreshToken, accessToken, expiresAt, etc.) to comply with better-auth requirements.
  • Username Field: Added an optional, unique username field to the User model. This acts as the primary indicator for whether a user has completed the onboarding flow.

2. Authentication Configuration

  • Configured Google and GitHub providers in src/lib/auth.ts.
  • Registered username under user.additionalFields in the better-auth configuration to expose it on the session object.

3. OAuth Routes & Controllers

  • Mounted better-auth's internal handlers at /api/auth/* in src/routes/index.ts.
  • Created a custom post-OAuth callback endpoint at GET /api/v1/auth/oauth/callback.
  • Implemented the oauthCallback controller:
    • Retrieves the current session using auth.api.getSession.
    • Redirects to FRONTEND_URL/onboarding if username is null (new user).
    • Redirects to FRONTEND_URL/dashboard if username is set (returning user).

4. Environment Configuration

  • Updated .env.example and src/lib/env.ts with OAuth credentials and frontend URL configurations:
    • GOOGLE_CLIENT_ID & GOOGLE_CLIENT_SECRET
    • GITHUB_CLIENT_ID & GITHUB_CLIENT_SECRET
    • FRONTEND_URL

Setup Instructions for Reviewers

  1. Copy the new variables from .env.example to your .env file and populate them with valid OAuth application credentials.
  2. Run database migrations to apply the schema changes: bun run db:migrate.
  3. In your Google/GitHub OAuth application settings, set the callback URLs to point to the better-auth endpoints (e.g., http://localhost:3000/api/auth/callback/google).

OAuth Authentication Implementation

  • Added OAuth login support for Google and GitHub providers
  • Automatic redirect-based onboarding flow:
    • New users are directed to the onboarding screen to complete their profile
    • Returning users are sent directly to the dashboard
  • Introduced username field as the primary indicator for tracking onboarding completion status
  • Updated database schema to support OAuth token management and user tracking
  • Configured necessary environment variables for OAuth credentials and frontend URL

@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@silky-x0, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 49 minutes and 27 seconds. Learn how PR review limits work.

To continue reviewing without waiting, enable usage-based billing in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a0dc83ca-4597-49d2-bdf8-3f46ee8ac15a

📥 Commits

Reviewing files that changed from the base of the PR and between 2a3f5d2 and f0197a8.

📒 Files selected for processing (1)
  • apps/api/src/controllers/oauth.controller.ts
📝 Walkthrough

Walkthrough

Adds Google and GitHub OAuth social login via better-auth. The Prisma Account model has OAuth token fields renamed from snake_case to camelCase, and a unique username field is added to User. Environment config gains OAuth credentials and a frontend URL. The auth library is configured with social providers and the username additional field. A new oauthCallback controller redirects authenticated users to onboarding or dashboard based on username presence, wired into the Express router.

Changes

OAuth Social Login

Layer / File(s) Summary
Database schema: Account field renames and username column
packages/db/prisma/schema/auth.prisma, packages/db/prisma/schema/user.prisma, packages/db/prisma/migrations/20260623000000_oauth_schema/migration.sql
Account OAuth token fields renamed from snake_case to camelCase (refreshToken, accessToken, expiresAt, tokenType, idToken, sessionState); User gains an optional unique username field; migration SQL applies both changes.
Environment config and auth library wiring
apps/api/src/lib/env.ts, apps/api/.env.example, apps/api/src/lib/auth.ts
config gains oauth (Google/GitHub credentials) and frontend.url sections; auth is extended with socialProviders for Google and GitHub and user.additionalFields.username defaulting to null.
OAuth callback controller and route
apps/api/src/controllers/oauth.controller.ts, apps/api/src/routes/user/oauth.routes.ts
oauthCallback reads the session from request headers, returns 401 when absent, and redirects to /onboarding or /dashboard based on username nullness; a new router wires this to GET /callback.
Express router wiring
apps/api/src/routes/index.ts
Adds a router.all("/api/auth/*", toNodeHandler(auth)) catch-all for better-auth and mounts the OAuth router at /api/v1/auth/oauth.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant BetterAuth as better-auth (/api/auth/*)
  participant OAuthCallback as oauthCallback (/api/v1/auth/oauth/callback)
  participant GoogleGitHub as Google / GitHub
  Client->>BetterAuth: GET /api/auth/signin/google (or github)
  BetterAuth->>GoogleGitHub: OAuth redirect
  GoogleGitHub-->>BetterAuth: Authorization code callback
  BetterAuth-->>Client: Session cookie set, redirect to /api/v1/auth/oauth/callback
  Client->>OAuthCallback: GET /callback (with session cookie)
  OAuthCallback->>BetterAuth: getSession(fromNodeHeaders)
  BetterAuth-->>OAuthCallback: session (user + username)
  alt username is null (new user)
    OAuthCallback-->>Client: redirect /onboarding
  else username exists (returning user)
    OAuthCallback-->>Client: redirect /dashboard
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Openlabsops/Snap-form#34: Established the initial better-auth email/password setup and base API routing in apps/api/src/lib/auth.ts, which this PR directly extends with social providers and additional fields.
  • Openlabsops/Snap-form#38: Introduced the modular prisma/schema/auth.prisma and user.prisma structure that this PR modifies to rename Account token fields and add User.username.

Poem

🐇 Hop, hop, here comes the OAuth hare,
Google and GitHub invited with care!
A username field, unique and bright,
Redirects to onboarding or dashboard at night.
Credentials tucked in .env with a wink —
Social login complete in a blink! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/oauth endpoints' is partially related to the changeset—it mentions OAuth endpoints, which is a key component, but omits the critical onboarding flow and database schema updates central to this work.
Linked Issues check ✅ Passed The PR successfully implements all requirements from issue #49: OAuth endpoints for Google and GitHub via better-auth [#49], session creation with conditional redirect logic for onboarding vs. dashboard [#49], and proper User/Session/Account schema structure via better-auth in auth.prisma [#49].
Out of Scope Changes check ✅ Passed All changes are directly aligned with OAuth authentication implementation and related infrastructure (environment config, database schema, routing) as specified in issue #49; no extraneous changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/src/controllers/oauth.controller.ts`:
- Around line 16-18: The destination assignment in the oauth.controller.ts file
only checks if session.user.username is null, but this allows empty strings and
other falsy values to pass through and incorrectly redirect to the dashboard.
Replace the null-only check with a presence check that evaluates the truthiness
of session.user.username so that any missing, empty, or falsy username value
will correctly redirect to the onboarding flow instead of the dashboard.

In `@apps/api/src/lib/auth.ts`:
- Around line 17-25: The socialProviders object unconditionally includes google
and github providers even when their credentials (clientId and clientSecret)
might be empty strings from the config.oauth object. Implement validation to
check if the required credentials for each provider exist and are not empty
before including them in the socialProviders configuration. Only add the google
provider if both config.oauth.googleClientId and config.oauth.googleClientSecret
are present with non-empty values, and similarly for the github provider with
config.oauth.githubClientId and config.oauth.githubClientSecret. This ensures
misconfiguration is caught immediately at startup rather than at runtime during
login attempts.

In `@apps/api/src/lib/env.ts`:
- Around line 9-17: The oauth configuration properties (googleClientId,
googleClientSecret, githubClientId, githubClientSecret) and the frontend URL are
using default fallback values that mask missing environment variables, allowing
the service to boot with broken OAuth setup. Remove the empty string defaults
for all OAuth properties and remove the localhost fallback for the frontend URL,
then add validation logic that throws an error at startup if any of these
required environment variables (GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, and FRONTEND_URL) are not provided. This
ensures the application fails fast with clear error messages rather than running
with incomplete configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 56513e64-6ab7-4559-8399-042dc6cca3d6

📥 Commits

Reviewing files that changed from the base of the PR and between 3c99a28 and 2a3f5d2.

📒 Files selected for processing (9)
  • apps/api/.env.example
  • apps/api/src/controllers/oauth.controller.ts
  • apps/api/src/lib/auth.ts
  • apps/api/src/lib/env.ts
  • apps/api/src/routes/index.ts
  • apps/api/src/routes/user/oauth.routes.ts
  • packages/db/prisma/migrations/20260623000000_oauth_schema/migration.sql
  • packages/db/prisma/schema/auth.prisma
  • packages/db/prisma/schema/user.prisma
📜 Review details
🧰 Additional context used
🪛 dotenv-linter (4.0.0)
apps/api/.env.example

[warning] 6-6: [UnorderedKey] The GOOGLE_CLIENT_ID key should go before the NODE_ENV key

(UnorderedKey)


[warning] 7-7: [UnorderedKey] The GOOGLE_CLIENT_SECRET key should go before the NODE_ENV key

(UnorderedKey)


[warning] 8-8: [UnorderedKey] The GITHUB_CLIENT_ID key should go before the GOOGLE_CLIENT_ID key

(UnorderedKey)


[warning] 9-9: [UnorderedKey] The GITHUB_CLIENT_SECRET key should go before the GOOGLE_CLIENT_ID key

(UnorderedKey)


[warning] 10-10: [UnorderedKey] The FRONTEND_URL key should go before the GITHUB_CLIENT_ID key

(UnorderedKey)

🔇 Additional comments (6)
packages/db/prisma/schema/auth.prisma (1)

33-39: LGTM!

apps/api/src/routes/user/oauth.routes.ts (1)

1-8: LGTM!

apps/api/src/routes/index.ts (1)

8-20: LGTM!

packages/db/prisma/schema/user.prisma (1)

21-21: LGTM!

packages/db/prisma/migrations/20260623000000_oauth_schema/migration.sql (1)

1-13: LGTM!

apps/api/.env.example (1)

6-10: LGTM!

Comment thread apps/api/src/controllers/oauth.controller.ts Outdated
Comment thread apps/api/src/lib/auth.ts
Comment thread apps/api/src/lib/env.ts

@Basharkhan7776 Basharkhan7776 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice will test and change in testing

@Basharkhan7776
Basharkhan7776 merged commit f74e8ee into Openlabsops:main Jun 23, 2026
3 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 30, 2026
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.

[Block] Index & Auth APIs

2 participants