Skip to content

Social login (Google, Facebook) and require login for idea submissions #44

Description

@mukto90

Problem

Anonymous visitors can vote, and (per the submission issue) would be able to submit ideas with an optional name/email. That makes submissions easy to spam, impossible to attribute, and gives the team no way to follow up with the person who asked. Asking visitors to register a WordPress account just to suggest an idea is too much friction, so they simply won't.

Proposal

Add social login (OAuth 2.0 / OpenID Connect) so visitors can sign in with one click, and require login to submit a feature request. Each submitted item records and shows who requested it.

1. Social login

Providers (v1): Google, Facebook. Next: Apple, GitHub, Microsoft, X. Build a provider adapter interface (authorize_url(), exchange_code(), get_profile()) so adding a provider is one class.

Flow

  1. Visitor clicks an action that needs login (Submit idea, optionally Vote/Comment per settings). A login modal opens on the board with provider buttons (plus WordPress username/password link for existing users).
  2. Redirect to provider using Authorization Code flow with PKCE and a one-time state bound to the session/cookie (CSRF protection). Return URL is stored server-side, validated against an allow-list of same-site URLs.
  3. Callback route (/?niroroadmap_oauth=google or REST GET /auth/{provider}/callback) exchanges the code, fetches the profile (id, name, email, email_verified, avatar), then logs the visitor into WordPress.
  4. Visitor returns to the board and their original action resumes (e.g. the submit form re-opens with the draft preserved).

Account handling

  • Table or user meta: niroroadmap_identities (user_id, provider, provider_user_id, created_at). One user can link several providers; unique on provider + provider_user_id.
  • Existing identity -> log in that user.
  • New identity, verified email matching an existing WP user -> link only after confirming (email confirmation link or log in with existing credentials). Never auto-link on an unverified email (account-takeover risk).
  • New identity, no match -> create a WP user with a dedicated low-privilege role (niroroadmap_member, capabilities: read only), random password, display_name from the provider, avatar stored as URL or imported.
  • Provider returns no email (Facebook may omit it) -> ask for an email on a small follow-up form and verify it before storing.
  • Setting: allow social sign-up even when users_can_register is off (default on, as these users are sandboxed).
  • Never assign roles from provider data. Never log in or create privileged users through this path.
  • Do not store provider access/refresh tokens unless a feature needs them; if stored, encrypt at rest.

2. Require login to submit

  • Submit form is only available to logged-in users (any WP user or social user). Logged-out visitors see "Sign in to suggest an idea" and the login modal.
  • REST POST /tasks/submit rejects unauthenticated requests with 401 and uses the cookie + X-WP-Nonce for authenticated ones (nonce must be refreshed by JS, so full-page caches don't break it).
  • Per-user rate limit (the existing Limiter trait is already user-meta based and can be reused here).
  • Setting for who may submit: logged-in users (default) / specific roles / everyone (legacy, discouraged).
  • Voting and commenting login requirements stay configurable (default: voting open, commenting requires login).

3. Show who requested it

  • Item stores the submitter as post_author (the post type already supports author), so it works with WP queries, capabilities and privacy tools.
  • Public display on the card/popup: avatar + "Requested by Jane D." Setting: full name / first name + last initial (default) / anonymous. Per-item "Hide requester" override for admins, and a "Submit anonymously" checkbox for users (shown as "A user").
  • Admin display: "Requested by" column on the items list and a box on the edit screen with name, email, login provider, profile link, user's other submissions and vote count; filter items by requester.
  • Optionally auto-add the requester's upvote.
  • Never expose email or provider IDs in public REST/HTML.

4. Admin settings (under Settings -> Login)

  • Enable/disable each provider; Client ID/Secret fields (secret stored masked, not echoed back).
  • Display the exact Redirect URI to paste into the Google/Facebook consoles, plus short setup docs link.
  • Button style/labels, default role, "display name" format, avatar import on/off.
  • "Test connection" action per provider.

5. Compatibility and extensibility

  • Hooks: niroroadmap_social_providers, niroroadmap_social_user_created, niroroadmap_social_profile filters/actions.
  • Detect common social-login plugins (Nextend, Super Socials, etc.) and let users reuse them: if the visitor is already logged in via any plugin, treat them as logged in. Offer a setting to show only the WordPress login link when another plugin handles auth.
  • Works with block and classic themes; modal is self-contained and does not rely on the theme's login page.

6. Privacy and compliance

  • Store only: name, email, avatar URL, provider ID. Add all of it to the WP personal-data exporter and eraser; erasing a user detaches or anonymises their items rather than deleting them (setting).
  • Consent text under the buttons ("By continuing you agree to the privacy policy"), linking to the site's privacy page.
  • Update readme.txt privacy section. Mention that provider sign-in contacts Google/Facebook only when a visitor clicks the button, never on page load (the plugin must keep making no external requests otherwise; important for wp.org guidelines and the existing privacy statement).

Acceptance criteria

  • A visitor can sign in with Google and with Facebook from the board modal and returns to where they were.
  • OAuth flow uses state + PKCE; tampered or replayed state is rejected; redirect targets are validated.
  • Same provider account always maps to the same WP user; no duplicate users on repeated login.
  • A verified-email match requires confirmation to link; an unverified email never links to an existing account.
  • Provider without an email prompts for and verifies an email.
  • New users get only the sandboxed niroroadmap_member role; provider data cannot change roles.
  • Anonymous POST /tasks/submit returns 401; logged-in users can submit, and submissions are rate limited per user.
  • Submitted items have post_author = requester; card/popup shows "Requested by" per the display setting; the anonymous option works.
  • Admin items list has a Requested by column and filter; edit screen shows requester details; email is never in public output.
  • Settings page shows redirect URIs; secrets are masked; disabled providers show no button.
  • Personal data export/erase covers identities and requester info.
  • No requests to Google/Facebook until the visitor clicks a provider button.
  • Works behind page caching and with the login modal keyboard accessible (focus trap, ESC, labelled buttons).
  • Tests: callback happy path, state mismatch, email-link rules, missing email, role assignment, unauthenticated submit, display-name formats.

Dependencies and impact on other issues

  • Settings page (provider credentials, login options).
  • Visitor idea submission: this issue changes its default. Submissions require login; the "optional name/email" fields and the anonymous-submit path in that issue should be dropped or kept only behind the "everyone" legacy setting.
  • Reuses fingerprint/rate-limit helpers from the vote-integrity issue; "logged-in users" weight and per-user vote budgets in the weighted-votes issue become possible.
  • Notification subscribers can default to the logged-in user's email.

Out of scope

Passwordless email magic links, SAML/enterprise SSO, using social login to log into wp-admin, importing contacts or social graph.

Priority rationale

Blocker for the submission flow: submissions now require an authenticated, attributable user.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureSomething we want to add

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions