Files
zeekay 6c65e3e941 @hanzo/app 0.2.0: the app SDK, renamed from @hanzo/rooms
Every import, the catalog pin and the docs name @hanzo/app and
github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and
components/rooms.tsx is components/app.tsx.
2026-10-22 19:07:20 -07:00

35 lines
1.6 KiB
TypeScript

import { team, visits } from '@hanzo/app/lib/host'
/**
* Who sent a person here to sign in, by where the code goes. A site on the web
* (platform.hanzo.ai, studio.hanzo.ai) names itself by its host, which is the
* callback IAM will hand the code to and checks against that client's own; a
* native app's callback (`hanzo://…`, a loopback port) names no site, so it is
* "an app on this device". Pure, so the sheet's words and its leaving are tested
* without a browser.
*/
export function asker(redirectUri: string | undefined): string | null {
try {
const to = new URL(redirectUri ?? '')
return to.protocol === 'https:' && to.hostname !== 'localhost' && to.hostname !== '127.0.0.1' ? to.host : null
} catch {
return null
}
}
/**
* Whether the code goes to a Hanzo site on the web: hanzo.ai or one of its hosts
* (platform.hanzo.ai, studio.hanzo.ai, admin.hanzo.ai, …), a host of this export
* (hanzo.bot) or the workspace (hanzo.team). Such a request is answered from the person's session here on
* arrival, with no sheet: a code reaches only the callback IAM has registered for
* that client, bound to the PKCE challenge and state the site's own page holds, so
* nobody but that site can redeem it. A native app's callback can be claimed by
* any app on the machine, and another site is asked about by name.
*/
export function ours(redirectUri: string | undefined): boolean {
const host = asker(redirectUri)
if (!host) return false
const name = host.split(':')[0]
return name === 'hanzo.ai' || name.endsWith('.hanzo.ai') || visits(name) || team(name)
}