🛡️Gatekeeper/ SDKs

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#

  1. Call mfa.enroll() while authenticated. It returns the TOTP secret, a qrCodeUri to render, and one-time recoveryCodes.

  2. Have the user scan the QR (or enter the secret) in their authenticator, then confirm with mfa.verifySetup(code).

  3. 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.

  1. Call auth.login(...). The result is either tokens or an { mfaRequired, challengeToken } challenge.

  2. If it is a challenge, collect a fresh TOTP code and call mfa.verifyChallenge(challengeToken, code) to receive the tokens.

  3. 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#

  1. Call oauth.authorize(provider) to get a redirect url and a state value. Persist state (for example in the session) and send the user to url.

  2. When the provider redirects back, read state and code from the query string and pass them to oauth.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);