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
- 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).
- 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.
- 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.
- 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
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.
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
statebound to the session/cookie (CSRF protection). Return URL is stored server-side, validated against an allow-list of same-site URLs./?niroroadmap_oauth=googleor RESTGET /auth/{provider}/callback) exchanges the code, fetches the profile (id, name, email, email_verified, avatar), then logs the visitor into WordPress.Account handling
niroroadmap_identities(user_id,provider,provider_user_id,created_at). One user can link several providers; unique onprovider + provider_user_id.niroroadmap_member, capabilities:readonly), random password,display_namefrom the provider, avatar stored as URL or imported.users_can_registeris off (default on, as these users are sandboxed).2. Require login to submit
POST /tasks/submitrejects unauthenticated requests with401and uses the cookie +X-WP-Noncefor authenticated ones (nonce must be refreshed by JS, so full-page caches don't break it).Limitertrait is already user-meta based and can be reused here).3. Show who requested it
post_author(the post type already supportsauthor), so it works with WP queries, capabilities and privacy tools.4. Admin settings (under Settings -> Login)
5. Compatibility and extensibility
niroroadmap_social_providers,niroroadmap_social_user_created,niroroadmap_social_profilefilters/actions.6. Privacy and compliance
readme.txtprivacy 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
state+ PKCE; tampered or replayedstateis rejected; redirect targets are validated.niroroadmap_memberrole; provider data cannot change roles.POST /tasks/submitreturns401; logged-in users can submit, and submissions are rate limited per user.post_author= requester; card/popup shows "Requested by" per the display setting; the anonymous option works.Dependencies and impact on other issues
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.