Skip to content

src/start-auth.ts

53 lines · 1.8 KB · TypeScript
Raw
import { saveAuthSession } from './auth-session.ts'
import { listLocaleCodes } from './locales.ts'
import { buildOAuthUrl, createCodeVerifier, shortAuthSessionId } from './login.ts'

export type StartAuthInput = {
	/** Marketplace country code (default us). */
	locale?: string
	/** Login with an Audible username instead of an Amazon account (DE/US/UK only). */
	withUsername?: boolean
}

/**
 * Begin Connect: return an Amazon OpenID+PKCE login URL and keep the PKCE
 * verifier in package storage for about 30 minutes. The owner signs in, then
 * passes the final maplanding URL to `./complete-auth`.
 *
 * @param input - Optional locale and withUsername flag
 * @returns loginUrl and authSessionId (no credentials)
 *
 * Internal: only the Connect page (`app.ts`) calls it.
 */
export default async function startAuth(input: StartAuthInput = {}) {
	const codeVerifier = createCodeVerifier()
	const authSessionId = shortAuthSessionId()
	const withUsername = Boolean(input.withUsername)
	const { loginUrl, serial, locale } = await buildOAuthUrl({
		locale: input.locale,
		codeVerifier,
		withUsername,
	})
	await saveAuthSession({
		authSessionId,
		codeVerifier,
		locale: locale.countryCode,
		serial,
		withUsername,
		createdAt: new Date().toISOString(),
	})
	return {
		ok: true as const,
		loginUrl,
		authSessionId,
		locale: locale.countryCode,
		supportedLocales: listLocaleCodes(),
		instructions: [
			`1. Open the login URL and sign in to Amazon (${locale.countryCode.toUpperCase()} marketplace).`,
			'2. Complete any CAPTCHA or 2FA in Amazon’s page.',
			'3. Amazon ends on an error page at …/ap/maplanding?… — that is expected.',
			'4. Paste that full URL into the app, or call complete-auth with { redirectUrl, authSessionId }.',
			`5. Session ${authSessionId} expires in about 30 minutes.`,
		].join('\n'),
	}
}