Documentation

Basic Workflow

  1. On your login page, a user submits their email
  2. Your backend calls the Yolotp API with the email
  3. Yolotp sends an OTP code to the submitted email
  4. On your login page, the user submits their OTP code
  5. Your backend calls the Yolotp API with the OTP code
  6. Yolotp validates the code and returns the result

API overview

The Yolotp API exposes four endpoints:

1. Generate OTP Code

POST https://yolotp.com/api/new
{
    "email": "example@yolotp.com"
}

2. Validate OTP Code

POST https://yolotp.com/api/check
{
    "email": "example@yolotp.com",
    "code": "AAHUOC"
}

3. Get User Details

GET https://yolotp.com/api/user/{userId}

4. Update User Details

POST https://yolotp.com/api/user/{userId}
{
    "email": "new-addy@example.com",
}

Next.js Integration Guide

This guide assumes you are using the App Router.

1. Install Next utilities

npm i @yolotp/next

2. Add the secret key to your environment variables

YOLOTP_SECRET_KEY=your_secret_key

3. Create your auth route handler

We'll assume you put this route at app/api/auth/route.ts.

export { GET, POST, DELETE } from "@yolotp/next/server";

4. Create your login page

"use client";

import { useState } from "react";

import { SessionStatus, useYolotp } from "@yolotp/next/client";

export default function Page() {
	const [checkCodeEmail, setCheckCodeEmail] = useState<string | undefined>();
	const {
		requestCode,
		loginWithCode,
		logout: yolotpLogout,
		status,
		user,
	} = useYolotp();

	async function getCode(e: React.FormEvent<HTMLFormElement>) {
		e.preventDefault();

		const data = new FormData(e.currentTarget);
		const email = data.get("email") as string;
		await requestCode({ email });

		setCheckCodeEmail(email);
	}

	async function checkCode(e: React.FormEvent<HTMLFormElement>) {
		e.preventDefault();
		const data = new FormData(e.currentTarget);
		const code = data.get("code") as string;

		await loginWithCode({ email: checkCodeEmail!, code });
		setCheckCodeEmail(undefined);
	}

	async function logout() {
		await yolotpLogout();
	}

	return (
		<div className="space-y-8">
			<h1 className="text-xl font-bold">Example App</h1>

			<div className="space-y-4 rounded border p-4">
				<h3 className="font-bold">Login Form</h3>

				{status === SessionStatus.LoggedOutEmailNeeded && (
					<form onSubmit={getCode} className="space-y-4">
						<div>
							<input
								name="email"
								type="email"
								placeholder="Email"
								className="border"
							/>
						</div>
						<button type="submit" className="border">
							Continue
						</button>
					</form>
				)}

				{status === SessionStatus.LoggedOutCodeNeeded && (
					<form onSubmit={checkCode} className="space-y-4">
						<div>
							<input
								name="code"
								type="text"
								placeholder="Code"
								className="border"
							/>
						</div>
						<button className="border" type="submit">
							Log In
						</button>
					</form>
				)}

				{status === SessionStatus.LoggedIn && (
					<button onClick={logout} type="button">
						Log Out
					</button>
				)}

				{status === SessionStatus.Initializing && (
					<p>Initializing...</p>
				)}

				{status === SessionStatus.Pending && <p>Loading...</p>}

				{status === SessionStatus.Error && <p>Error!</p>}
			</div>

			<div className="space-y-4 rounded border bg-slate-100 p-4">
				<h3 className="font-bold">Session Data</h3>
				<p>{JSON.stringify(user)}</p>
			</div>
		</div>
	);
}