This guide covers two sign-in paths. First, TOTP MFA: enroll, confirm the authenticator with a code, stash recovery codes, and complete the challenge that login returns once MFA is active. Second, the OAuth redirect flow: get an authorize URL, then exchange the provider's callback for tokens.
Enroll TOTP MFA#
-
Call
mfa.enroll()while authenticated. It returns the TOTPsecret, aqrCodeUrito render, and one-timerecoveryCodes. -
Have the user scan the QR (or enter the secret) in their authenticator, then confirm with
mfa.verifySetup(code). -
Store the recovery codes somewhere the user can reach if they lose their device.
import { GatekeeperCore, MfaService } from '@orkait/sdk';
const core = new GatekeeperCore({ baseUrl: 'https://gatekeeper-api.example.workers.dev' });
core.setToken(accessToken);
const mfa = new MfaService(core);
// 1. Begin enrollment - render qrCodeUri, keep recoveryCodes for the user.
const enrollment = await mfa.enroll();
console.log(enrollment.qrCodeUri);
console.log('recovery codes:', enrollment.recoveryCodes);
// 2. Confirm the authenticator with a current TOTP code.
await mfa.verifySetup('123456');The login challenge flow#
Once MFA is active, login may return a challenge instead of tokens. Detect it with the isMfaChallenge (TS) / is_mfa_challenge (Python) helper, then complete it with verifyChallenge.
-
Call
auth.login(...). The result is either tokens or an{ mfaRequired, challengeToken }challenge. -
If it is a challenge, collect a fresh TOTP code and call
mfa.verifyChallenge(challengeToken, code)to receive the tokens. -
Set the access token on the core.
import { GatekeeperCore, AuthService, MfaService, isMfaChallenge } from '@orkait/sdk';
const core = new GatekeeperCore({ baseUrl: 'https://gatekeeper-api.example.workers.dev' });
const auth = new AuthService(core);
const mfa = new MfaService(core);
const result = await auth.login({ email: 'owner@acme.com', password: 'hunter2-strong-pass' });
let tokens;
if (isMfaChallenge(result)) {
// result.challengeToken is short-lived; prompt for a code now.
tokens = await mfa.verifyChallenge(result.challengeToken, '123456');
} else {
tokens = result;
}
core.setToken(tokens.accessToken);OAuth authorize and callback#
-
Call
oauth.authorize(provider)to get a redirecturland astatevalue. Persiststate(for example in the session) and send the user tourl. -
When the provider redirects back, read
stateandcodefrom the query string and pass them tooauth.callback(provider, ...)to receive tokens.
import { GatekeeperCore, OAuthService } from '@orkait/sdk';
const core = new GatekeeperCore({ baseUrl: 'https://gatekeeper-api.example.workers.dev' });
const oauth = new OAuthService(core);
// 1. Start the flow - persist state, redirect the user to url.
const { url, state } = await oauth.authorize('google');
// saveToSession(state); redirect(url);
// 2. On the callback route, exchange state + code for tokens.
const tokens = await oauth.callback('google', {
state, // the value you persisted
code: incomingQuery.code,
});
core.setToken(tokens.accessToken);