mirror of
https://github.com/hanzoai/js-sdk.git
synced 2026-10-30 15:02:31 +00:00
cloud's openapi.yaml now has a `bearer` securityScheme and a top-level
`security`, so regenerating turns 2498 operations from "imports
setBearerAuthToObject and calls it nowhere" into a real
`Authorization: Bearer` write from `configuration.accessToken`. The four
operations marked `security: []` — /v1/models, /v1/models/providers,
/v1/commands, /v1/openapi.json — generate no auth call, so commands-api.ts
is the one api file of 192 without one.
That retires `baseOptions: { headers: { Authorization } }`, which existed
only because a document with no scheme made `accessToken` inert. One field,
one header, one way; examples/client.ts and the docs say so.
examples/models is new and needs no credential, so a reader can run the
client against the live API before holding a key. Measured, not assumed:
models prints 112 models anonymously, hello prints
`sub admin/hanzo-cloud in org hanzo` with an IAM client-credentials token
and 401 invalid_token with a bad one, and money reads the org's own balance
where anonymous reads account "anonymous".
.spec-lock: hanzoai/cloud@113cf7d6, sha256 a50fc96c.
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
// hello — who am I?
|
|
//
|
|
// GET /v1/iam/oauth/userinfo (get_iam_oauth_userinfo), the OIDC identity
|
|
// endpoint of the one IAM.
|
|
//
|
|
// This flow's job is to FAIL on a bad key, so the route has to be one that
|
|
// refuses. Two identity-shaped neighbours do not: /v1/iam/whoami answers 200
|
|
// with {"status":"error"} and /v1/ai/account answers 200 type="anonymous-user"
|
|
// to a request carrying no header at all. Either would print a cheerful
|
|
// identity for a key that is refused everywhere else. userinfo answers 401
|
|
// {"error":"invalid_token"}.
|
|
//
|
|
// The body is read through a cast because this operation declares no response
|
|
// schema — one of 891 in the document that state the route and not its shape.
|
|
import { IamApi } from 'hanzoai';
|
|
import { config, basePath, fail } from '../client';
|
|
|
|
type UserInfo = {
|
|
sub?: string;
|
|
name?: string;
|
|
preferred_username?: string;
|
|
email?: string;
|
|
organization?: string;
|
|
iss?: string;
|
|
};
|
|
|
|
async function main() {
|
|
const iam = new IamApi(config());
|
|
const { data } = await iam.getIamOauthUserinfo();
|
|
const me = data as unknown as UserInfo;
|
|
|
|
console.log(`hello from ${basePath}`);
|
|
console.log(` sub ${me.sub ?? '(none)'} in org ${me.organization ?? '(none)'}`);
|
|
console.log(` ${me.name ?? me.preferred_username ?? '(unnamed)'} <${me.email ?? 'no email'}>`);
|
|
console.log(` issued by ${me.iss ?? '(unknown issuer)'}`);
|
|
}
|
|
|
|
main().catch(fail);
|