Skip to content

Zintrust recipe ​

Zintrust (@zintrust/core) has no built-in social login, so this recipe uses its router and controller APIs. The browser runs universal-social-auth. The Zintrust server exchanges the code and keeps the client secret.

1. Route ​

routes/api.ts:

typescript
import { router } from '@zintrust/core';
import { SocialAuthController } from '../app/Controllers/SocialAuthController';

router.post('/auth/google', 'SocialAuthController@google');

2. Controller ​

app/Controllers/SocialAuthController.ts (sealed namespace pattern from the Zintrust docs):

typescript
import type { IRequest, IResponse } from '@zintrust/core';

const GOOGLE_TOKEN_URL = 'https://oauth2.googleapis.com/token';

export const SocialAuthController = Object.freeze({
  create() {
    return {
      async google(req: IRequest, res: IResponse): Promise<void> {
        const body = req.body as {
          code?: string;
          codeVerifier?: string;
          redirectUri?: string;
        };

        if (!body.code || !body.codeVerifier || !body.redirectUri) {
          return res.status(422).json({ message: 'Missing code, codeVerifier, or redirectUri' });
        }

        const tokenResponse = await fetch(GOOGLE_TOKEN_URL, {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: new URLSearchParams({
            code: body.code,
            client_id: process.env.GOOGLE_CLIENT_ID ?? '',
            client_secret: process.env.GOOGLE_CLIENT_SECRET ?? '',
            redirect_uri: body.redirectUri,
            grant_type: 'authorization_code',
            code_verifier: body.codeVerifier,
          }),
        });

        if (!tokenResponse.ok) {
          return res.status(401).json({ message: 'Token exchange failed' });
        }

        // Verify the id_token (signature, iss, aud, nonce) before trusting it.
        // Then create or log in the local user and issue your app session.
        return res.json({ ok: true });
      },
    };
  },
});

Check the exact res.status() and res.json() signatures in your installed @zintrust/core version. This recipe was written against its routing and controller docs and has not been run against a live Zintrust app.

Related: Express recipe, Laravel recipe.

Released under the MIT License. Published by Diadal Nigeria Limited. Part of the Zintrust ecosystem at zintrust.com.