Why authentication matters in a MAM app
A MAM app is a native front end for a WordPress site, so “who is signed in” is the
hinge that everything personal swings on: a user’s orders, favorites, profile fields,
push tokens, and the role-specific content the app shows them. Authentication in MAM
is not a bolt-on — it is the bridge between a person tapping Sign in on a phone and
a real WordPress user account, with a real role, on your site.
Here’s the mental model worth holding onto: every login method ends at the same
place. No matter how a user proves who they are — an emailed code, an Apple ID, a
password, an SMS code — the result is the same: a resolved WordPress user, a role
assigned to that user, and a per-role mobile payload built just for them. The methods
only differ in how the user proves identity, never in what they produce. Once that
single funnel clicks, everything else on this page falls into place.
This whole subsystem lives in mam-main, under includes/user-roles/ — it’s the
single largest behavioral area of the core plugin. The login flow itself is handled by
mam_login_manager (in login-manager.php), and role assignment by
mam_user_roles_manager (in mam-user-roles.php).
The authentication methods
A MAM app can offer four broad ways to sign in. Which ones appear on the login screen
is controlled by app settings, so a given app might show one, two, or all of them.
1. Email and password (standard)
The classic path: the user enters an email address and a password. New users can create
an account the same way (a Sign up with Email option), and existing users sign in
with the credentials they set.
- Turned on with the Allow user to sign up with Email setting (
sign_up_with_email). - Optionally, Require email validation during account setup
(sign_up_with_email_validation) holds the new account inactive until the user
confirms a code sent to their email — this blocks fake or mistyped addresses. - A Forgot Password? link drives the password-reset flow (send a code, then set a
new password). It can be hidden with Hide Forgot Password Button
(login_hide_lost_password) for apps that don’t use passwords at all.
Under the hood these are the login and signup tasks, routed by mam_login_manager,
which checks the password against WordPress’s own password hashing before letting the
user in.
2. Emailed one-time code (“magic link” / passwordless)
Instead of relying only on a password, the app can send the user a one-time code to
their email address — no password to remember or mistype. In the source this code is
delivered by the mam-user-roles-login-with-email notification type, and the same
mechanism actually does double duty: it powers the Require email validation during
account setup step (which holds a new account inactive until the user enters the
code) and the Forgot Password? reset (which mails a reset code). The code-entry UI
itself is driven by the signup-code settings — the Send Code button label
(login_send_code_button_title), the code-field placeholder
(login_sign_up_code_placeholder), and the reminder text shown near the field
(login_sign_up_code_reminder).
3. Social login (Apple and Google)
The user signs in with an identity they already have — Sign in with Apple or
Sign in with Google — instead of creating an email/password pair.
- Turned on with Allow user to sign up with Apple and Google
(sign_up_with_google). - Google additionally requires a Google Login API client ID
(login_google_client_id), obtained from the Google Cloud Console OAuth credentials.
Behind the scenes these are the oauth_apple and oauth_google tasks. MAM first looks
for an existing user by their stable provider identifier (the Apple/Google “subject”);
if it doesn’t find one, it tries matching by email; if neither matches, it can create
the account. You can also configure the app to verify the provider’s signed identity
token — checking it against Apple’s or Google’s published keys — so a forged sign-in
can’t impersonate one of your users.
4. Phone code (SMS verification)
The user receives a numeric code by SMS and enters it to verify a phone number. This is
a distinct flow from the login methods above: it is handled by mam_validate_phone_code
(in phone-code-validation.php), which generates a code and dispatches it through the
MAM notification system’s SMS channel, then verifies the code the user types back.
Worth being precise about scope here: phone-code validation is the mechanism for
proving someone owns a phone number, nothing more. Whether it shows up as a standalone
way to sign in, or as a verification step within signup or profile editing, comes
down to how the app is configured. Don’t confuse it with the one-shot phone validation
that happens during a form submission — that’s a separate notification type
(gf-phone-number-validation).
How a login maps to a role
This is the part that trips up people coming from a pure WordPress background, so it’s
worth stating plainly: a successful login always results in a WordPress role being
assigned, and that role drives what the app shows.
When a brand-new user is created through any of the methods above, MAM hands them a
default role. Out of the box that’s subscriber, but you can change it: the
default is read from a “new user role” app setting (in the source,
tsl-setting-new_user_role), and only falls back to subscriber if that setting is
empty or invalid. So you can set up an app so everyone who signs up lands as, say, a
member or a custom role you’ve defined.
Here’s what follows from that:
- Role decides the app payload. MAM builds a per-role mobile JSON payload — the
tabs, menu, and content a user sees are put together specifically for their role.
Two users signing in with identical credentials but different roles end up looking at
different apps. - Invited users get promoted. A special
invitedrole covers accounts that were
pre-created for someone (caregiver invitations, for example). Once that user finishes
signing up, MAM removesinvitedand swaps in the real default role. - Admins can preview as a role. “Cloning” is MAM’s term for an admin previewing the
app as though they were another role. Any code that gates on role should account for
this instead of reading the raw user role. - Extension points exist around creation. Sibling plugins can hook into the
create-user lifecycle (for examplemam_user_roles_before_create_userand
mam_user_roles_after_create_user) to enrich or veto the new account, and
mam_user_logged_infires after a successful login.
The takeaway: the login method is about authentication (proving who you are); the role
is about authorization (what you may see and do). MAM ties them together at the moment
of account creation and re-checks the role on each login.
What “require login” gating means
The Require Login? setting (require_login) decides whether signing in is mandatory
or optional — and that one switch changes the very first thing a user sees when they
open your app:
- Require Login = Yes. The login screen is the first screen. Users must sign in (or
create an account) before they can reach any content. Use this for apps where
everything is members-only. - Require Login = No. The app opens straight to its content, and signing in is
optional. Users browse anonymously and log in later only when they want to reach
account-gated features — favorites, orders, their profile, and anything else that
depends on having a user and a role.
So “gating” really happens at two levels, and it helps to keep them separate.
App-level gating is the require_login switch: is a login required to use the app
at all? Feature-level gating is finer-grained: even in a no-login app, individual
features that need a user (and therefore a role) will prompt the user to sign in right
at the point they’re used. The first is one global toggle; the second is just an
inherent property of any feature that reads per-user or per-role data.
One more thing worth knowing: require_login is global — it applies across all
roles, because at the moment the gate gets evaluated, the app doesn’t yet know which
role the user is about to become.
How it all connects
Put all the pieces together and here’s the lifecycle of a signed-in MAM user, start to
finish:
- The login screen offers whichever methods the app’s settings enable — email/password,
magic-link code, Apple/Google, and/or phone-code. - The user proves identity through one of those methods. All of them funnel into
mam_login_manager, which resolves (or creates) a WordPress user. - On account creation, MAM assigns the default role (
subscriberunless configured
otherwise), promotinginvitedusers as needed. - MAM builds the per-role mobile payload, and the app renders the experience for that
role. require_logindecides whether step 1 is mandatory up front or deferred until a
user taps into an account-gated feature.
Because every method ends at the same WordPress-user-plus-role outcome, you can mix and
match login methods without changing anything downstream: the same roles, the same
content rules, the same hooks all apply regardless of how the user got in.
Related
- App Setting: Require Login? (
require_login) - App Setting: Allow user to sign up with Email (
sign_up_with_email) - App Setting: Require email validation during account setup
(sign_up_with_email_validation) - App Setting: Allow user to sign up with Apple and Google (
sign_up_with_google) - App Setting: Google Login API (
login_google_client_id) - App Setting: Hide Forgot Password Button (
login_hide_lost_password) - App Setting: Send Code Button Title (
login_send_code_button_title)
What’s next
- Concept: Roles and the per-role mobile payload — how a user’s role shapes the tabs,
menu, and content the app renders. - Recipe: Configuring your app’s login screen and methods — the step-by-step for
turning each method on and styling the screen.
