Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Sign in With Ethereum #330

Merged
merged 2 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/b2b/organizations_members.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion dist/b2c/crypto_wallets.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 13 additions & 13 deletions dist/b2c/m2m.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions dist/b2c/sessions.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions lib/b2b/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,22 @@ export interface Member {
*/
is_admin: boolean;
totp_registration_id: string;
/**
*
* A list of retired email addresses for this member.
* A previously active email address can be marked as retired in one of two ways:
* - It's replaced with a new primary email address during an explicit Member update.
* - A new email address is surfaced by an OAuth, SAML or OIDC provider. In this case the new email
* address becomes the
* Member's primary email address and the old primary email address is retired.
*
* A retired email address cannot be used by other Members in the same Organization. However, unlinking
* retired email
* addresses allows them to be subsequently re-used by other Organization Members. Retired email
* addresses can be unlinked
* using the [Unlink Retired Email endpoint](https://stytch.com/docs/b2b/api/unlink-retired-member-email).
*
*/
retired_email_addresses: RetiredEmail[];
/**
* Sets whether the Member is enrolled in MFA. If true, the Member must complete an MFA step whenever they
Expand Down Expand Up @@ -419,7 +435,9 @@ export interface Organization {
}

export interface RetiredEmail {
// The globally unique UUID of a Member's email.
email_id: string;
// The email address of the Member.
email_address: string;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/b2b/organizations_members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ export class Members {
*
* A retired email address cannot be used by other Members in the same Organization. However, unlinking
* retired email
* addresses allows then to be subsequently re-used by other Organization Members. Retired email addresses
* addresses allows them to be subsequently re-used by other Organization Members. Retired email addresses
* can be viewed
* on the [Member object](https://stytch.com/docs/b2b/api/member-object).
* %}
Expand Down
1 change: 1 addition & 0 deletions lib/b2b/scim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export interface SCIMGroup {
}

export interface SCIMGroupImplicitRoleAssignments {
// The ID of the role.
role_id: string;
group_id: string;
group_name: string;
Expand Down
4 changes: 4 additions & 0 deletions lib/b2b/scim_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ export interface B2BSCIMConnectionUpdateRequest {
| "pingfederate"
| "rippling"
| string;
/**
* An array of SCIM group implicit role assignments. Each object in the array must contain a `group` and a
* `role_id`.
*/
scim_group_implicit_role_assignments?: SCIMGroupImplicitRoleAssignments[];
}

Expand Down
73 changes: 72 additions & 1 deletion lib/b2c/crypto_wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,41 @@ import { request } from "../shared";
import { Session } from "./sessions";
import { User } from "./users";

export interface SIWEParams {
/**
* Only required if `siwe_params` is passed. The domain that is requesting the crypto wallet signature.
* Must be an RFC 3986 authority.
*/
domain: string;
/**
* Only required if `siwe_params` is passed. An RFC 3986 URI referring to the resource that is the subject
* of the signing.
*/
uri: string;
/**
* A list of information or references to information the user wishes to have resolved as part of
* authentication. Every resource must be an RFC 3986 URI.
*/
resources: string[];
// The EIP-155 Chain ID to which the session is bound. Defaults to 1.
chain_id?: number;
// A human-readable ASCII assertion that the user will sign.
statement?: string;
/**
* The time when the message was generated. Defaults to the current time. All timestamps in our API conform
* to the RFC 3339 standard and are expressed in UTC, e.g. `2021-12-29T12:33:09Z`.
*/
issued_at?: string;
/**
* The time when the signed authentication message will become valid. Defaults to the current time. All
* timestamps in our API conform to the RFC 3339 standard and are expressed in UTC, e.g.
* `2021-12-29T12:33:09Z`.
*/
not_before?: string;
// A system-specific identifier that may be used to uniquely refer to the sign-in request.
message_request_id?: string;
}

// Request type for `cryptoWallets.authenticate`.
export interface CryptoWalletsAuthenticateRequest {
/**
Expand Down Expand Up @@ -84,6 +119,8 @@ export interface CryptoWalletsAuthenticateResponse {
*
*/
session?: Session;
// The parameters of the Sign In With Ethereum (SIWE) message that was signed.
siwe_params?: CryptoWalletsSIWEParamsResponse;
}

// Request type for `cryptoWallets.authenticateStart`.
Expand All @@ -102,6 +139,11 @@ export interface CryptoWalletsAuthenticateStartRequest {
session_token?: string;
// The `session_jwt` associated with a User's existing Session.
session_jwt?: string;
/**
* The parameters for a Sign In With Ethereum (SIWE) message. May only be passed if the
* `crypto_wallet_type` is `ethereum`.
*/
siwe_params?: SIWEParams;
}

// Response type for `cryptoWallets.authenticateStart`.
Expand All @@ -124,6 +166,28 @@ export interface CryptoWalletsAuthenticateStartResponse {
status_code: number;
}

export interface CryptoWalletsSIWEParamsResponse {
// The domain that requested the crypto wallet signature.
domain: string;
// An RFC 3986 URI referring to the resource that is the subject of the signing.
uri: string;
// The EIP-155 Chain ID to which the session is bound.
chain_id: number;
/**
* A list of information or references to information the user wishes to have resolved as part of
* authentication. Every resource must be an RFC 3986 URI.
*/
resources: string[];
status_code: number;
/**
* The time when the message was generated. All timestamps in our API conform to the RFC 3339 standard and
* are expressed in UTC, e.g. `2021-12-29T12:33:09Z`.
*/
issued_at?: string;
// A system-specific identifier that may be used to uniquely refer to the sign-in request.
message_request_id?: string;
}

export class CryptoWallets {
private fetchConfig: fetchConfig;

Expand All @@ -133,7 +197,14 @@ export class CryptoWallets {

/**
* Initiate the authentication of a crypto wallet. After calling this endpoint, the user will need to sign
* a message containing only the returned `challenge` field.
* a message containing the returned `challenge` field.
*
* For Ethereum crypto wallets, you can optionally use the Sign In With Ethereum (SIWE) protocol for the
* message by passing in the `siwe_params`. The only required fields are `domain` and `uri`.
* If the crypto wallet detects that the domain in the message does not match the website's domain, it will
* display a warning to the user.
*
* If not using the SIWE protocol, the message will simply consist of the project name and a random string.
* @param data {@link CryptoWalletsAuthenticateStartRequest}
* @returns {@link CryptoWalletsAuthenticateStartResponse}
* @async
Expand Down
2 changes: 2 additions & 0 deletions lib/b2c/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,12 @@ export type {
} from "./sessions";

export type {
SIWEParams,
CryptoWalletsAuthenticateRequest,
CryptoWalletsAuthenticateResponse,
CryptoWalletsAuthenticateStartRequest,
CryptoWalletsAuthenticateStartResponse,
CryptoWalletsSIWEParamsResponse,
} from "./crypto_wallets";

export type {
Expand Down
26 changes: 13 additions & 13 deletions lib/b2c/m2m.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,19 +241,19 @@ export class M2M {
// ADDIMPORT: import { performAuthorizationCheck, ScopeAuthorizationFunc } from "./m2m_local";
// ADDIMPORT: import { ClientError } from "../shared/errors";
/**
* Authenticate an access token issued by Stytch from the Token endpoint.
* M2M access tokens are JWTs signed with the project's JWKs, and can be validated locally using any Stytch client library.
* You may pass in an optional set of scopes that the JWT must contain in order to enforce permissions.
* You may also override the default scope authorization function to implement custom authorization logic.
*
* @param data {@link AuthenticateTokenRequest}
* @param scopeAuthorizationFunc {@link ScopeAuthorizationFunc} - A function that checks if the token has the required scopes.
The default function assumes scopes are either direct string matches or written in the form "action:resource". See the
documentation for {@link performAuthorizationCheck} for more information.
* @async
* @returns {@link AuthenticateTokenResponse}
* @throws {ClientError} when token can not be authenticated
*/
* Authenticate an access token issued by Stytch from the Token endpoint.
* M2M access tokens are JWTs signed with the project's JWKs, and can be validated locally using any Stytch client library.
* You may pass in an optional set of scopes that the JWT must contain in order to enforce permissions.
* You may also override the default scope authorization function to implement custom authorization logic.
*
* @param data {@link AuthenticateTokenRequest}
* @param scopeAuthorizationFunc {@link ScopeAuthorizationFunc} - A function that checks if the token has the required scopes.
The default function assumes scopes are either direct string matches or written in the form "action:resource". See the
documentation for {@link performAuthorizationCheck} for more information.
* @async
* @returns {@link AuthenticateTokenResponse}
* @throws {ClientError} when token can not be authenticated
*/
async authenticateToken(
data: AuthenticateTokenRequest,
scopeAuthorizationFunc: ScopeAuthorizationFunc = performAuthorizationCheck
Expand Down
49 changes: 49 additions & 0 deletions lib/b2c/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,19 +507,63 @@ export interface SessionsGetResponse {
status_code: number;
}

// Request type for `sessions.migrate`.
export interface SessionsMigrateRequest {
// The `session_token` associated with a User's existing Session.
session_token: string;
/**
* Set the session lifetime to be this many minutes from now. This will start a new session if one doesn't
* already exist,
* returning both an opaque `session_token` and `session_jwt` for this session. Remember that the
* `session_jwt` will have a fixed lifetime of
* five minutes regardless of the underlying session duration, and will need to be refreshed over time.
*
* This value must be a minimum of 5 and a maximum of 527040 minutes (366 days).
*
* If a `session_token` or `session_jwt` is provided then a successful authentication will continue to
* extend the session this many minutes.
*
* If the `session_duration_minutes` parameter is not specified, a Stytch session will not be created.
*/
session_duration_minutes?: number;
/**
* Add a custom claims map to the Session being authenticated. Claims are only created if a Session is
* initialized by providing a value in `session_duration_minutes`. Claims will be included on the Session
* object and in the JWT. To update a key in an existing Session, supply a new value. To delete a key,
* supply a null value.
*
* Custom claims made with reserved claims ("iss", "sub", "aud", "exp", "nbf", "iat", "jti") will be
* ignored. Total custom claims size cannot exceed four kilobytes.
*/
session_custom_claims?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
}

// Response type for `sessions.migrate`.
export interface SessionsMigrateResponse {
/**
* Globally unique UUID that is returned with every API call. This value is important to log for debugging
* purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
*/
request_id: string;
// The unique ID of the affected User.
user_id: string;
// A secret token for a given Stytch Session.
session_token: string;
// The JSON Web Token (JWT) for a given Stytch Session.
session_jwt: string;
/**
* The `user` object affected by this API call. See the
* [Get user endpoint](https://stytch.com/docs/api/get-user) for complete response field details.
*/
user: User;
status_code: number;
/**
* If you initiate a Session, by including `session_duration_minutes` in your authenticate call, you'll
* receive a full Session object in the response.
*
* See [GET sessions](https://stytch.com/docs/api/session-get) for complete response fields.
*
*/
session?: Session;
}

Expand Down Expand Up @@ -678,6 +722,11 @@ export class Sessions {
}

/**
* Migrate a session from an external OIDC compliant endpoint. Stytch will call the external UserInfo
* endpoint defined in your Stytch Project settings in the [Dashboard](/dashboard), and then perform a
* lookup using the `session_token`. If the response contains a valid email address, Stytch will attempt to
* match that email address with an existing User and create a Stytch Session. You will need to create the
* user before using this endpoint.
* @param data {@link SessionsMigrateRequest}
* @returns {@link SessionsMigrateResponse}
* @async
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stytch",
"version": "11.0.0",
"version": "11.1.0",
"description": "A wrapper for the Stytch API",
"types": "./types/lib/index.d.ts",
"main": "./dist/index.js",
Expand Down
Loading
Loading