Feat: Legacy Auth Parity for Eyebrow + Magic Login Flows#303
Feat: Legacy Auth Parity for Eyebrow + Magic Login Flows#303OtavioXimarelli wants to merge 5 commits into
Conversation
- Add EyebrowBar component (fixed above nav for unauthenticated users) - Email input + Continue CTA - Handles 4 email states: registered, not_requested, requested_pending, approved_no_password - Magic link login and password login options for registered users - Auto-submits invite request for brand new emails - Hides entirely when user is authenticated - Mobile-responsive layout - CSS var --eyebrow-height to offset AppBar and content - Add MagicLoginPage (/auth/magic-login?token=...) - Validates token via verifyUserPasswordResetToken query - Dispatches USER_LOGIN_SUCCESS and redirects to /search - Add checkEmailStatus GraphQL query (server) - Returns status: registered | not_requested | requested_pending | approved_no_password - Public (no auth required) - Add sendMagicLoginLink GraphQL mutation (server) - Generates 15-min JWT token via addCreatorToUser - Sends email via SendGrid MAGIC_LOGIN template - Public (no auth required) - Update GraphQL type definitions and resolver registrations - Mark checkEmailStatus and sendMagicLoginLink as public in requireAuth - Add MAGIC_LOGIN template ID to SendGrid constants Closes QuoteVote#295
✅ Deploy Preview for quotevote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
I've achieved code parity between the two repos. Let me know what you think and if anything else is needed, thank you! @flyblackbox. |
There was a problem hiding this comment.
Pull request overview
This PR aligns the legacy app’s guest auth entry points with the newer implementation by adding backend support for email-status branching + onboarding-link delivery, and updating the client eyebrow CTA and magic-login route to use those parity flows with targeted tests.
Changes:
- Added server GraphQL query/mutations for
checkEmailStatus,sendMagicLoginLink, andsendOnboardingCompletionLink, plus public access wiring and tests. - Introduced a global guest
EyebrowBarthat branches by email status and drives modal flows (invite request, magic link, onboarding completion). - Added
/auth/magic-loginpage + tests, and updated layout offsets to account for the eyebrow height.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| server/app/tests/queries/user/checkEmailStatus.test.js | Adds query-level test coverage for new email-status branching. |
| server/app/tests/mutations/user/sendOnboardingCompletionLink.test.js | Adds mutation tests for onboarding completion link behavior. |
| server/app/tests/mutations/user/sendMagicLoginLink.test.js | Adds mutation tests for magic login link behavior. |
| server/app/data/utils/send-grid-mail.js | Adds SendGrid template ID for the new magic-login email. |
| server/app/data/utils/requireAuth.js | Allows unauthenticated access to new auth-parity operations. |
| server/app/data/type_definition/query_definition.js | Adds checkEmailStatus to the GraphQL schema. |
| server/app/data/type_definition/mutation_definition.js | Adds sendMagicLoginLink + sendOnboardingCompletionLink to the schema. |
| server/app/data/resolvers/queries/user/index.js | Re-exports the new checkEmailStatus query resolver. |
| server/app/data/resolvers/queries/user/checkEmailStatus.js | Implements email status lookup for eyebrow branching. |
| server/app/data/resolvers/queries.js | Wires checkEmailStatus into the root query map. |
| server/app/data/resolvers/mutations/user/sendOnboardingCompletionLink.js | Implements onboarding completion link email sending for approved users without passwords. |
| server/app/data/resolvers/mutations/user/sendMagicLoginLink.js | Implements magic login email sending for registered users. |
| server/app/data/resolvers/mutations/user/index.js | Re-exports new user mutations. |
| server/app/data/resolvers/mutations.js | Wires new mutations into the root mutation map. |
| client/src/views/MagicLoginPage/MagicLoginPage.test.jsx | Adds UI tests for token handling, messaging, dispatch, and redirect. |
| client/src/views/MagicLoginPage/MagicLoginPage.jsx | Adds magic-login verification + login dispatch + redirect flow. |
| client/src/mui-pro/mui-routes.jsx | Adds the /auth/magic-login route. |
| client/src/main.jsx | Mounts EyebrowBar globally above routing. |
| client/src/graphql/query.jsx | Adds CHECK_EMAIL_STATUS query definition. |
| client/src/graphql/mutations.jsx | Adds SEND_MAGIC_LOGIN_LINK + SEND_ONBOARDING_COMPLETION_LINK mutations. |
| client/src/components/Navbars/MainNavBar.jsx | Offsets fixed navbar by --eyebrow-height for layout parity. |
| client/src/components/EyebrowBar/EyebrowBar.test.jsx | Adds tests for all eyebrow flow branches and dismissal. |
| client/src/components/EyebrowBar/EyebrowBar.jsx | Adds new guest eyebrow component with modal-based auth flows. |
| client/src/assets/jss/material-dashboard-pro-react/layouts/adminStyle.jsx | Updates top margin calculations to include eyebrow height. |
| PR_DESCRIPTION.md | Updates PR description to reflect the parity/auth changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| const user = await UserModel.findOne({ | ||
| email: { $regex: new RegExp(`^${email.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'i') }, |
| const { email } = args; | ||
| const user = await UserModel.findOne({ | ||
| email: { $regex: new RegExp(`^${email.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'i') }, | ||
| }); | ||
|
|
| } | ||
|
|
||
| if (!user.hash_password) { | ||
| return { success: false, message: 'This account has not completed signup yet.' }; |
| const user = await UserModel.findOne({ | ||
| email: { | ||
| $regex: new RegExp( | ||
| `^${email.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, | ||
| 'i', | ||
| ), | ||
| }, |
| 'checkEmailStatus', | ||
| 'sendMagicLoginLink', | ||
| 'sendOnboardingCompletionLink', |
| // Dispatch login success with user data | ||
| dispatch( | ||
| USER_LOGIN_SUCCESS({ | ||
| data: user, |
| await new Promise((resolve) => { | ||
| setTimeout(resolve, 1100) | ||
| }) | ||
|
|
||
| expect(mockPush).toHaveBeenCalledWith('/search') |
|
@OtavioXimarelli Do you know why I get the error "Continue |
There was a problem hiding this comment.
Pull request overview
Aligns the legacy monorepo auth/onboarding entry behavior with the Next implementation by adding missing backend support for email-status branching and onboarding-link delivery, and updating the client “eyebrow” + magic-login flows with parity-focused UX and regression tests.
Changes:
- Added backend
checkEmailStatusquery plus publicsendMagicLoginLink/sendOnboardingCompletionLinkmutations for parity flows. - Implemented new client
EyebrowBarCTA flow and/auth/magic-loginpage with corresponding GraphQL contract updates. - Added targeted client/server test coverage for the new parity paths and introduced request-id logging/correlation.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| server/app/tests/queries/user/checkEmailStatus.test.js | Adds unit tests for checkEmailStatus resolver status branching + validation error handling. |
| server/app/tests/mutations/user/sendOnboardingCompletionLink.test.js | Adds unit tests for onboarding-link mutation behavior (eligible vs ineligible). |
| server/app/tests/mutations/user/sendMagicLoginLink.test.js | Adds unit tests for magic-login link mutation (unknown, incomplete, registered). |
| server/app/server.js | Adds request-id plumbing + GraphQL request logging; updates Apollo context to include requestId. |
| server/app/data/utils/send-grid-mail.js | Adds MAGIC_LOGIN template ID and includes request-id in SendGrid-related logs. |
| server/app/data/utils/requireAuth.js | Allows new query/mutations to be called without authentication. |
| server/app/data/type_definition/query_definition.js | Adds GraphQL schema entry for checkEmailStatus. |
| server/app/data/type_definition/mutation_definition.js | Adds schema entries for sendMagicLoginLink and sendOnboardingCompletionLink. |
| server/app/data/resolvers/queries/user/index.js | Re-exports checkEmailStatus query resolver. |
| server/app/data/resolvers/queries/user/checkEmailStatus.js | Implements email status branching for eyebrow CTA flow. |
| server/app/data/resolvers/queries.js | Wires checkEmailStatus into root resolver map. |
| server/app/data/resolvers/mutations/userInvite/requestUserAccess.js | Threads requestId into logs and email send call for invite-request confirmation. |
| server/app/data/resolvers/mutations/user/sendOnboardingCompletionLink.js | Implements onboarding completion link email send for approved/no-password users. |
| server/app/data/resolvers/mutations/user/sendMagicLoginLink.js | Implements magic login link email send for registered users. |
| server/app/data/resolvers/mutations/user/index.js | Exports the new user mutations and restores star-exports list. |
| server/app/data/resolvers/mutations.js | Wires new mutations into root mutation map. |
| client/src/views/MagicLoginPage/MagicLoginPage.test.jsx | Adds MagicLogin page tests for token missing/invalid/valid/expired behaviors. |
| client/src/views/MagicLoginPage/MagicLoginPage.jsx | Adds MagicLogin page that verifies token, dispatches login, and redirects. |
| client/src/mui-pro/mui-routes.jsx | Adds /auth/magic-login route entry. |
| client/src/main.jsx | Mounts the EyebrowBar globally above routing. |
| client/src/graphql/query.jsx | Adds CHECK_EMAIL_STATUS client query. |
| client/src/graphql/mutations.jsx | Adds SEND_MAGIC_LOGIN_LINK and SEND_ONBOARDING_COMPLETION_LINK mutations. |
| client/src/config/apollo.js | Optionally adds an x-request-id header per request for correlation. |
| client/src/components/Navbars/MainNavBar.jsx | Offsets fixed AppBar by --eyebrow-height so layout accounts for eyebrow banner. |
| client/src/components/EyebrowBar/EyebrowBar.test.jsx | Adds eyebrow CTA flow tests across status branches + dismissal. |
| client/src/components/EyebrowBar/EyebrowBar.jsx | Implements new eyebrow CTA branching flow with modals + email normalization. |
| client/src/assets/jss/material-dashboard-pro-react/layouts/adminStyle.jsx | Updates layout top margins to include --eyebrow-height. |
| PR_DESCRIPTION.md | Updates PR description to reflect the new parity/auth scope. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| setTimeout(() => { | ||
| history.push('/search') | ||
| }, 1000) |
| logger.warn('CORS blocked request origin', { | ||
| requestId: req.requestId, | ||
| origin, | ||
| method: req.method, | ||
| path: req.path, |
| setFeedback('Sending login link...') | ||
| const { data } = await sendMagicLink({ variables: { email } }) | ||
| const result = data?.sendMagicLoginLink | ||
|
|
| try { | ||
| setFeedback('Sending onboarding link...') | ||
| const { data } = await sendOnboardingCompletionLink({ | ||
| variables: { email }, |
Eyebrow Auth FlowLocal backend is working and tests pass for eyebrow-related GraphQL operations. Production What Is Verified Locally
Local Test Results (Passed)
Production SymptomsObserved responses from
Interpretation: this is not a client payload-shape issue; production runtime/schema does not match the verified local backend. |
|
The production backend ( ✅ Local VerificationThe local backend is fully verified and tests pass for the eyebrow auth flow operations:
🛠️ Action Items (Railway Checks)To proceed with the debugging, I need some checks on the actual deployed backend. Please verify the following: 1. Source & Build Artifacts
2. Runtime Environment VariablesConfirm the following variables are properly set in the production environment:
3. Production Smoke ChecksOnce the deployment is confirmed to be running the latest artifact, please run smoke checks for these specific GraphQL fields:
|
|
Uh oh... that doesn't sound good. Do you know how to resolve this @OtavioXimarelli? |
|
Sorry for the delay, @flyblackbox. I've been very busy lately, and unfortunately, this seems out of my league right now. However, I'm open to working on any other issue you might need help with. Thank you again! |
|
Ok @OtavioXimarelli understood, no worries. I will think about it and get back to you soon. Thank you for volunteering! |
Feat: Legacy Auth Parity for Eyebrow + Magic Login Flows
Description
This PR brings the legacy monorepo behavior in line with the Next implementation for the guest eyebrow CTA and magic-login/onboarding entry points.
It adds the missing backend onboarding-link mutation, updates the eyebrow UX to handle all status branches consistently, and adds targeted test coverage for critical parity paths on both client and server.
Changes
Eyebrow CTA parity (
client)EyebrowBarflow to branch bycheckEmailStatusand show modal-based actions for:registered-> login options modal (magic link or password login)approved_no_password-> onboarding completion modal--eyebrow-height).trim) before network calls.success/message) instead of assuming transport-level success.Client GraphQL contract updates
SEND_ONBOARDING_COMPLETION_LINKmutation inclient/src/graphql/mutations.jsx.Magic login page hardening (
client)Backend parity (
server)sendOnboardingCompletionLink:/auth/signup?token=...onboarding link for approved users without passwordssendOnboardingCompletionLink(email: String!): JSON.requireAuthallowlist.Automated tests added
client/src/components/EyebrowBar/EyebrowBar.test.jsxclient/src/views/MagicLoginPage/MagicLoginPage.test.jsxserver/app/tests/queries/user/checkEmailStatus.test.jsserver/app/tests/mutations/user/sendMagicLoginLink.test.jsserver/app/tests/mutations/user/sendOnboardingCompletionLink.test.jsVerification
Client tests
npm run test -- src/components/EyebrowBar/EyebrowBar.test.jsx src/views/MagicLoginPage/MagicLoginPage.test.jsxServer tests
npm run test -- --runInBand app/tests/queries/user/checkEmailStatus.test.js app/tests/mutations/user/sendMagicLoginLink.test.js app/tests/mutations/user/sendOnboardingCompletionLink.test.jsLint / style
@/...imports.Notes