Skip to content
Docs
Reference

BackstageClient.identity

BackstageClient.identity in @ticketlayer/backstage.

@ticketlayer/backstage


@ticketlayer/backstage / BackstageClient / identity

identity: {
  abortSignInInteraction: (uid: string, requestOptions?: RequestOptions) => Promise<{
     redirectTo: string;
     status: "continue";
  }>;
  emailCode: (request: {
     authSession: string;
     code?: string;
   }, requestOptions?: RequestOptions) => Promise<
     | {
     code: string;
     redirectUri: string;
     status: "code";
   }
     | {
     authSession: string;
     factors: ("email" | "totp")[];
     status: "mfa_required";
   }
     | {
     status: "code_sent";
  }>;
  getSignInInteraction: (uid: string, requestOptions?: RequestOptions) => Promise<{
     account?: {
        email: string;
        name: string | null;
     };
     client:   | {
        clientUri: string | null;
        firstParty: boolean;
        id: string;
        logoUri: string | null;
        name: string;
      }
        | null;
     organisation?: {
        id: string;
        name: string;
        slug: string;
     };
     organisations?: {
        id: string;
        name: string;
        slug: string;
     }[];
     prompt: {
        details: {
         [key: string]: unknown;
        };
        name: string;
        reasons: string[];
     };
     scopeDetails: {
        description: string;
        kind: "identity" | "platform" | "resource";
        label: string;
        scope: string;
     }[];
     scopes: string[];
     signedIn: boolean;
     uid: string;
  }>;
  invitationAccept: (request: {
     authSession: string;
     firstName: string;
     lastName?: string;
     password: string;
   }, requestOptions?: RequestOptions) => Promise<
     | {
     code: string;
     redirectUri: string;
     status: "code";
   }
     | {
     authSession: string;
     factors: ("email" | "totp")[];
     status: "mfa_required";
  }>;
  invitationStart: (request: {
     client_id: string;
     code_challenge: string;
     code_challenge_method?: "S256";
     dpop_jkt?: string;
     invitation: string;
     redirect_uri?: string;
     scope?: string;
   }, requestOptions?: RequestOptions) => Promise<{
     alternatives: "email_code"[];
     authSession: string;
     email: string;
     expiresIn: number;
     method: "password" | "set_password";
     organisation: {
        name: string;
        slug: string;
     };
  }>;
  mfa: (request: {
     authSession: string;
     code: string;
   }, requestOptions?: RequestOptions) => Promise<
     | {
     code: string;
     redirectUri: string;
     status: "code";
   }
     | {
     authSession: string;
     factors: ("email" | "totp")[];
     status: "mfa_required";
  }>;
  password: (request: {
     authSession: string;
     password: string;
   }, requestOptions?: RequestOptions) => Promise<
     | {
     code: string;
     redirectUri: string;
     status: "code";
   }
     | {
     authSession: string;
     factors: ("email" | "totp")[];
     status: "mfa_required";
  }>;
  signupStart: (request: {
     client_id: string;
     code_challenge: string;
     code_challenge_method?: "S256";
     dpop_jkt?: string;
     email: string;
     redirect_uri?: string;
     scope?: string;
   }, requestOptions?: RequestOptions) => Promise<{
     authSession: string;
     expiresIn: number;
     status: "code_sent";
  }>;
  signupVerify: (request: {
     authSession: string;
     code: string;
     firstName: string;
     lastName?: string;
     password: string;
   }, requestOptions?: RequestOptions) => Promise<
     | {
     code: string;
     redirectUri: string;
     status: "code";
   }
     | {
     authSession: string;
     factors: ("email" | "totp")[];
     status: "mfa_required";
  }>;
  start: (request: {
     client_id: string;
     code_challenge: string;
     code_challenge_method?: "S256";
     dpop_jkt?: string;
     email: string;
     organisation?: string;
     redirect_uri?: string;
     scope?: string;
   }, requestOptions?: RequestOptions) => Promise<{
     alternatives: "email_code"[];
     authSession: string;
     expiresIn: number;
     method: "password";
  }>;
  submitSignInInteractionConsent: (uid: string, requestOptions?: RequestOptions) => Promise<{
     redirectTo: string;
     status: "continue";
  }>;
  submitSignInInteractionLogin: (uid: string, request: {
     code?: string;
     email: string;
     password: string;
  }, requestOptions?: RequestOptions) => Promise<any>;
  submitSignInInteractionOrganisation: (uid: string, request: {
     organisation: string;
   }, requestOptions?: RequestOptions) => Promise<{
     redirectTo: string;
     status: "continue";
  }>;
  switchSignInInteraction: (uid: string, request: {
     target: "account" | "organisation";
   }, requestOptions?: RequestOptions) => Promise<{
     redirectTo: string;
     status: "continue";
  }>;
};

Defined in: client.ts:1421

Identity methods

abortSignInInteraction()#

abortSignInInteraction: (uid: string, requestOptions?: RequestOptions) => Promise<{
  redirectTo: string;
  status: "continue";
}>;

Decline or cancel a pending authorisation

Parameters#

ParameterType
uidstring
requestOptions?RequestOptions

Returns#

Promise<{ redirectTo: string; status: "continue"; }>

Operation Id#

abortSignInInteraction

emailCode()#

emailCode: (request: {
  authSession: string;
  code?: string;
}, requestOptions?: RequestOptions) => Promise<
  | {
  code: string;
  redirectUri: string;
  status: "code";
}
  | {
  authSession: string;
  factors: ("email" | "totp")[];
  status: "mfa_required";
}
  | {
  status: "code_sent";
}>;

Sign in with an emailed code Without code: email a sign-in code to the address, if it has an account, and answer code_sent either way. With code: sign in with it.

Parameters#

ParameterTypeDescription
request{ authSession: string; code?: string; }-
request.authSessionstringDescription The handle start answered.
request.code?string-
requestOptions?RequestOptions-

Returns#

Promise< | { code: string; redirectUri: string; status: "code"; } | { authSession: string; factors: ("email" | "totp")[]; status: "mfa_required"; } | { status: "code_sent"; }>

Operation Id#

submitSignInEmailCode

getSignInInteraction()#

getSignInInteraction: (uid: string, requestOptions?: RequestOptions) => Promise<{
  account?: {
     email: string;
     name: string | null;
  };
  client:   | {
     clientUri: string | null;
     firstParty: boolean;
     id: string;
     logoUri: string | null;
     name: string;
   }
     | null;
  organisation?: {
     id: string;
     name: string;
     slug: string;
  };
  organisations?: {
     id: string;
     name: string;
     slug: string;
  }[];
  prompt: {
     details: {
      [key: string]: unknown;
     };
     name: string;
     reasons: string[];
  };
  scopeDetails: {
     description: string;
     kind: "identity" | "platform" | "resource";
     label: string;
     scope: string;
  }[];
  scopes: string[];
  signedIn: boolean;
  uid: string;
}>;

Describe a pending sign-in What the issuer-side sign-in page should show for an authorisation a third party or a device started: the step it is waiting for, the client asking, the scopes, and the organisations to pick from.

Parameters#

ParameterType
uidstring
requestOptions?RequestOptions

Returns#

Promise<{ account?: { email: string; name: string | null; }; client: | { clientUri: string | null; firstParty: boolean; id: string; logoUri: string | null; name: string; } | null; organisation?: { id: string; name: string; slug: string; }; organisations?: { id: string; name: string; slug: string; }[]; prompt: { details: { [key: string]: unknown; }; name: string; reasons: string[]; }; scopeDetails: { description: string; kind: "identity" | "platform" | "resource"; label: string; scope: string; }[]; scopes: string[]; signedIn: boolean; uid: string; }>

Operation Id#

getSignInInteraction

invitationAccept()#

invitationAccept: (request: {
  authSession: string;
  firstName: string;
  lastName?: string;
  password: string;
}, requestOptions?: RequestOptions) => Promise<
  | {
  code: string;
  redirectUri: string;
  status: "code";
}
  | {
  authSession: string;
  factors: ("email" | "totp")[];
  status: "mfa_required";
}>;

Accept an invitation with a new password For an invitation whose address has no account (set_password): a password and a name. The invitation code proved the address, so the person is created verified, the invitation is accepted, and the answer is a one-time authorization code whose tokens are pinned to the organisation. 409 EMAIL_ALREADY_REGISTERED when the address has an account: sign in instead.

Parameters#

ParameterTypeDescription
request{ authSession: string; firstName: string; lastName?: string; password: string; }-
request.authSessionstringDescription The handle start answered.
request.firstName?stringExample Ada
request.lastName?stringExample Lovelace
request.password?stringDescription The password to set: at least 12 characters (400 PASSWORD_TOO_SHORT otherwise).
requestOptions?RequestOptions-

Returns#

Promise< | { code: string; redirectUri: string; status: "code"; } | { authSession: string; factors: ("email" | "totp")[]; status: "mfa_required"; }>

Operation Id#

acceptInvitationSignIn

invitationStart()#

invitationStart: (request: {
  client_id: string;
  code_challenge: string;
  code_challenge_method?: "S256";
  dpop_jkt?: string;
  invitation: string;
  redirect_uri?: string;
  scope?: string;
}, requestOptions?: RequestOptions) => Promise<{
  alternatives: "email_code"[];
  authSession: string;
  email: string;
  expiresIn: number;
  method: "password" | "set_password";
  organisation: {
     name: string;
     slug: string;
  };
}>;

Start accepting an invitation The first step of accepting an invitation to an organisation, from one of Ticketlayer's own apps. Takes the client, its PKCE S256 challenge and the invitation code from the email, and answers the address and organisation it is for and how to continue: password when the address has an account (then /auth/password, /auth/email-code or /auth/mfa with the handle, as for any sign-in), set_password when it has none (/auth/invitations/accept). The last step accepts the invitation - the person becomes a member with the roles it names - and its code gives tokens pinned to that organisation. 404 INVITATION_NOT_FOUND, 410 INVITATION_EXPIRED or 409 INVITATION_ALREADY_REDEEMED otherwise. Rate limited as start is.

Parameters#

ParameterTypeDescription
request{ client_id: string; code_challenge: string; code_challenge_method?: "S256"; dpop_jkt?: string; invitation: string; redirect_uri?: string; scope?: string; }-
request.client_idstring-
request.code_challenge?string-
request.code_challenge_method?"S256"
request.dpop_jkt?string-
request.invitation?stringDescription The code from the invitation email (?code= in its link).
request.redirect_uri?string-
request.scope?string-
requestOptions?RequestOptions-

Returns#

Promise<{ alternatives: "email_code"[]; authSession: string; email: string; expiresIn: number; method: "password" | "set_password"; organisation: { name: string; slug: string; }; }>

Operation Id#

startInvitationSignIn

mfa()#

mfa: (request: {
  authSession: string;
  code: string;
}, requestOptions?: RequestOptions) => Promise<
  | {
  code: string;
  redirectUri: string;
  status: "code";
}
  | {
  authSession: string;
  factors: ("email" | "totp")[];
  status: "mfa_required";
}>;

Complete a sign-in with a second factor

Parameters#

ParameterTypeDescription
request{ authSession: string; code: string; }-
request.authSessionstringDescription The handle start answered.
request.code?string-
requestOptions?RequestOptions-

Returns#

Promise< | { code: string; redirectUri: string; status: "code"; } | { authSession: string; factors: ("email" | "totp")[]; status: "mfa_required"; }>

Operation Id#

submitSignInMfa

password()#

password: (request: {
  authSession: string;
  password: string;
}, requestOptions?: RequestOptions) => Promise<
  | {
  code: string;
  redirectUri: string;
  status: "code";
}
  | {
  authSession: string;
  factors: ("email" | "totp")[];
  status: "mfa_required";
}>;

Sign in with a password

Parameters#

ParameterTypeDescription
request{ authSession: string; password: string; }-
request.authSessionstringDescription The handle start answered.
request.password?string-
requestOptions?RequestOptions-

Returns#

Promise< | { code: string; redirectUri: string; status: "code"; } | { authSession: string; factors: ("email" | "totp")[]; status: "mfa_required"; }>

Operation Id#

submitSignInPassword

signupStart()#

signupStart: (request: {
  client_id: string;
  code_challenge: string;
  code_challenge_method?: "S256";
  dpop_jkt?: string;
  email: string;
  redirect_uri?: string;
  scope?: string;
}, requestOptions?: RequestOptions) => Promise<{
  authSession: string;
  expiresIn: number;
  status: "code_sent";
}>;

Start a sign-up The first step of creating a Ticketlayer account from one of Ticketlayer's own apps. Takes the client, its PKCE S256 challenge and the email address, and emails a six-digit code to the address. The answer is the same whether or not the address already has an account: one that does is emailed a note to sign in instead, and no code can finish its sign-up. Rate limited as start is, and emailed codes per address per hour. First-party clients only.

Parameters#

ParameterTypeDescription
request{ client_id: string; code_challenge: string; code_challenge_method?: "S256"; dpop_jkt?: string; email: string; redirect_uri?: string; scope?: string; }-
request.client_idstring-
request.code_challenge?string-
request.code_challenge_method?"S256"
request.dpop_jkt?string-
request.email?string-
request.redirect_uri?string-
request.scope?string-
requestOptions?RequestOptions-

Returns#

Promise<{ authSession: string; expiresIn: number; status: "code_sent"; }>

Operation Id#

startSignUp

signupVerify()#

signupVerify: (request: {
  authSession: string;
  code: string;
  firstName: string;
  lastName?: string;
  password: string;
}, requestOptions?: RequestOptions) => Promise<
  | {
  code: string;
  redirectUri: string;
  status: "code";
}
  | {
  authSession: string;
  factors: ("email" | "totp")[];
  status: "mfa_required";
}>;

Finish a sign-up The emailed code, a password and a name. Creates the person, with the address verified, and answers a one-time authorization code for /oauth/token. The tokens it gives name no organisation (org_slug null): they reach POST /signup, which creates the person's first organisation, and GET /me/organisations, and nothing else. Every wrong, spent or expired code answers the same 401. Five guesses per code.

Parameters#

ParameterTypeDescription
request{ authSession: string; code: string; firstName: string; lastName?: string; password: string; }-
request.authSessionstringDescription The handle start answered.
request.code?string-
request.firstName?stringExample Ada
request.lastName?stringExample Lovelace
request.password?stringDescription The password to set: at least 12 characters (400 PASSWORD_TOO_SHORT otherwise).
requestOptions?RequestOptions-

Returns#

Promise< | { code: string; redirectUri: string; status: "code"; } | { authSession: string; factors: ("email" | "totp")[]; status: "mfa_required"; }>

Operation Id#

verifySignUp

start()#

start: (request: {
  client_id: string;
  code_challenge: string;
  code_challenge_method?: "S256";
  dpop_jkt?: string;
  email: string;
  organisation?: string;
  redirect_uri?: string;
  scope?: string;
}, requestOptions?: RequestOptions) => Promise<{
  alternatives: "email_code"[];
  authSession: string;
  expiresIn: number;
  method: "password";
}>;

Start a first-party sign-in The first step of signing in to one of Ticketlayer's own apps. Takes the client, its PKCE S256 challenge and the email address, and answers a handle for the steps that follow and the method to use. The answer is the same whether or not the address has an account. Only first-party clients are accepted. dpop_jkt binds the code this sign-in ends with to a DPoP key (RFC 9449), and is also what the per-installation rate limit counts.

Parameters#

ParameterTypeDescription
request{ client_id: string; code_challenge: string; code_challenge_method?: "S256"; dpop_jkt?: string; email: string; organisation?: string; redirect_uri?: string; scope?: string; }-
request.client_idstring-
request.code_challenge?string-
request.code_challenge_method?"S256"
request.dpop_jkt?string-
request.email?string-
request.organisation?stringDescription An organisation slug to pin the first token to. Without one, the person's only organisation, or none.
request.redirect_uri?string-
request.scope?string-
requestOptions?RequestOptions-

Returns#

Promise<{ alternatives: "email_code"[]; authSession: string; expiresIn: number; method: "password"; }>

Operation Id#

startSignIn

submitSignInInteractionConsent()#

submitSignInInteractionConsent: (uid: string, requestOptions?: RequestOptions) => Promise<{
  redirectTo: string;
  status: "continue";
}>;

Approve a client for a pending authorisation Grants the client what it asked for, in the organisation this authorisation is for. The approval is remembered per person, client and organisation, so the same client asking again for no more does not ask again.

Parameters#

ParameterType
uidstring
requestOptions?RequestOptions

Returns#

Promise<{ redirectTo: string; status: "continue"; }>

Operation Id#

submitSignInInteractionConsent

submitSignInInteractionLogin()#

submitSignInInteractionLogin: (uid: string, request: {
  code?: string;
  email: string;
  password: string;
}, requestOptions?: RequestOptions) => Promise<any>;

Sign in to a pending authorisation Email and password, then a second factor when the person has one: the first answer is then second_factor_required (and an emailed code is sent when that is a factor), and the same call with code finishes. Rate limited per address signed in to and per sign-in. The answer never says whether an account exists.

Parameters#

ParameterTypeDescription
uidstring-
request{ code?: string; email: string; password: string; }-
request.code?stringDescription A TOTP or emailed code, on the second call.
request.email?string-
request.password?string-
requestOptions?RequestOptions-

Returns#

Promise<any>

Operation Id#

submitSignInInteractionLogin

submitSignInInteractionOrganisation()#

submitSignInInteractionOrganisation: (uid: string, request: {
  organisation: string;
}, requestOptions?: RequestOptions) => Promise<{
  redirectTo: string;
  status: "continue";
}>;

Choose the organisation for a pending authorisation

Parameters#

ParameterTypeDescription
uidstring-
request{ organisation: string; }-
request.organisationstringDescription The slug Example acme-events
requestOptions?RequestOptions-

Returns#

Promise<{ redirectTo: string; status: "continue"; }>

Operation Id#

submitSignInInteractionOrganisation

switchSignInInteraction()#

switchSignInInteraction: (uid: string, request: {
  target: "account" | "organisation";
}, requestOptions?: RequestOptions) => Promise<{
  redirectTo: string;
  status: "continue";
}>;

Change the account or organisation of a pending authorisation From the consent or organisation step: start the same authorisation again for someone else (account, which asks for a sign-in) or with the organisation picker offered again (organisation). The client is not denied; the answer is where the browser goes next.

Parameters#

ParameterTypeDescription
uidstring-
request{ target: "account" | "organisation"; }-
request.target"account" | "organisation"
requestOptions?RequestOptions-

Returns#

Promise<{ redirectTo: string; status: "continue"; }>

Operation Id#

switchSignInInteraction