Zindua

PushMirror

1-tap sign-in challenges inside your app or browser. Approve, deny, or match an emoji or digit. No extra consumer app to install. Same API key as email and WhatsApp.

npm install @zindua/sdk

@zindua/sdk v1.4.0

Interactive schematic

PushMirror. Inside your product.

PushMirror mark by default, Powered by Zindua signature, check + celebration when approved. This is the same sheet your users see.

app.yours.com/login

New machine sign-in

Check your phone

😄

Tap the same icon on your trusted device.

Trusted phone

Your app

PushMirror · now

Allow this sign-in?

Chrome · Kinshasa · just now

Powered by Zindua

WhatsApp interactive

Zero-app path. Approve, deny, or match on the WhatsApp line linked to your Zindua project.

Web Push

Native browser notifications on Chrome, Safari, Firefox, and PWAs. Trusted device without a store app.

BYO FCM / APNs

Use your Firebase or APNs keys so the challenge lands inside the app your users already installed.

Emoji match

Login screen shows one icon. The push offers a few choices. Harder to phish aloud than a spoken code.

Realtime SSE

Browser login listens for approve or deny. No heavy polling. Session continues when the phone confirms.

OTP fallback

No trusted device or timeout? Fall back to WhatsApp or email OTP on the same project and API key.

Who does what

You own the app. We own the challenge.

PushMirror orchestrates the challenge. Your WhatsApp line, Web Push, or FCM/APNs delivers it.

Your user

Has your app installed, or allowed Web Push on your site. No Zindua consumer app.

Your backend

Creates the challenge with @zindua/sdk (pushMirror), shows display on login, listens for the result.

PushMirror

Orchestrates challenge state, choices, expiry, webhooks, logs, and OTP fallback. Not a marketing push ESP.

Scenario

From login screen to trusted device

How PushMirror interacts with your product when a user signs in from a new browser or phone.

01

User signs in

On web or a new device, your app starts login. You call PushMirror from the backend only.

02

PushMirror creates the challenge

We mint challenge id, type (approve, emoji, or digit), display target, choices, and expiry.

03

Push reaches a trusted device

Delivered via WhatsApp interactive, Web Push, or your FCM / APNs app. Payload includes context: device, city, time.

04

User responds on the phone

Approve / deny, or tap the matching emoji or digit shown on the login screen.

05

Your login unlocks

SSE or webhook tells your backend. Create the session. On deny or timeout, block or fall back to OTP.

Challenge types

Approve, emoji, or digit

Same API. Pick the UX that fits your risk and product tone.

Approve / Deny

approve

C'est moi · Ce n'est pas moi

Best for “someone is signing in from Chrome · Kinshasa”. One tap. Classic PushMirror approve flow.

Emoji match

emoji

😄 🚀 🔒 🌴

Login screen shows one emoji. Push shows 3–5 options. User taps the same one. Stops simple push phishing.

Digit match

digit

42 · 17 · 83 · 09

Login shows a two-digit number. User picks the same number on the trusted device.

Setup

Wire PushMirror into your project

Four steps from API key to a live challenge on login.

01

Create a Zindua project

Sign in, create a project, copy your znd_live_ or znd_test_ key. Same key as email and WhatsApp.

02

Pick a delivery path

Link WhatsApp for interactive prompts, enable Web Push, or attach your FCM / APNs credentials (BYO).

03

Register trusted devices

After a successful login, register the device token (FCM, APNs, or Web Push) against your user id.

04

Create + listen on login

pushMirror.create from the server. Show challenge.display. pushMirror.listen (SSE) or webhook to open the session.

SDK & stacks

Same key. PushMirror on every stack.

Official guides with the same icons as the Developers menu. Each card links to its page. WordPress is a plugin download, not a Composer package.

Next.js

Official

pushMirror.create + SSE listen + webhook HMAC on the server.

npm install @zindua/sdkOpen Next.js guide

Fastify

Official

Node backend with @zindua/sdk. Add Fastify as your HTTP framework.

npm install @zindua/sdkOpen Fastify guide

FastAPI / Python

Official

Async create_challenge and Depends() patterns.

pip install zindua-sdkOpen FastAPI guide

PHP / Laravel

Official

createChallenge + signed webhook helpers.

composer require zindua/sdkOpen PHP guide

.NET / C#

Official

AddZindua + CreateChallengeAsync for ASP.NET Core.

dotnet add package Zindua.SdkOpen .NET guide

WordPress

Plugin

Download the Zindua Connect plugin for OTP login and WooCommerce. No Composer command.

Download WordPress plugin

Flutter

Coming soon

Register token via POST /devices. Render PushMirror UI from the FCM payload.

Firebase + Flutter steps

Firebase FCM

BYO

Paste your FCM server key under Push → Config. Full mobile guide.

Open mobile guide

iOS / APNs

BYO

Upload your APNs key in Firebase, then use the same FCM path as Android.

Open iOS / APNs guide

Flutter SDK is on the roadmap. Until then, call POST /api/v1/challenges from your Dart backend or BFF, and handle the FCM / APNs payload in your Flutter app with the same challenge id + respond endpoint.

import { Zindua } from "@zindua/sdk";

const zindua = new Zindua({ apiKey: process.env.ZINDUA_API_KEY! });

// Backend: start a PushMirror challenge when the user tries to sign in
const challenge = await zindua.pushMirror.create({
  to: "+243832499559", // or userId / userExternalId for device lookup
  type: "emoji", // "emoji" | "approve" | "digit"
  purpose: "login",
  channel: "auto", // auto | whatsapp | webpush | fcm | byo
  context: { device: "Chrome on macOS", city: "Kinshasa" },
  fallbackChannel: "whatsapp",
});

// Login UI: show challenge.display (e.g. 😄 or 42)
// Trusted device: user taps the matching choice in your app / WhatsApp / Web Push

await zindua.pushMirror.listen(challenge.challengeId, {
  onApproved: () => {
    // create session / redirect
  },
  onDenied: () => {
    // block or alert
  },
});
BYO push · Android & iOS

Mobile integration has its own guide

Open mobile guide

Beginner → intermediate → advanced tracks: where to put znd_live_, znd_sec_, and the FCM key; Firebase Console steps; project tree; SSE vs webhooks; emoji / digit / approve with a live phone demo.

Product

Built for real login flows

Context, webhooks, and fallback so PushMirror sits next to your existing OTP.

Realtime SSE

The login page learns the result as soon as the phone responds. Keep the UX instant without hammering HTTP.

Brandable prompts

Set app name and logo in the developer dashboard so the challenge feels like your product, not a generic alert.

Signed webhooks

Get challenge.approved, denied, or expired on your backend with HMAC verification for audit and risk rules.

Context in every prompt

Pass device, city, IP, and purpose so users recognize a home login vs a suspicious one. Clear PushMirror context every time.

Ready to try PushMirror?

Create a project, link WhatsApp or Web Push, then ship one-tap sign-in with OTP fallback.