import { GraphqlClient } from '../common/GraphqlClient'; import { HttpClient } from '../common/HttpClient'; import { AuthenticationTokenProvider } from './AuthenticationTokenProvider'; import { Lang, Encryption } from '../../types'; /** * 初始化 AuthenticationClientOptions 的参数 */ export interface AuthenticationClientOptions { /** 应用 ID */ appId: string; /** 租户 ID */ tenantId?: string; /** 应用完整域名,如 https://sample-app.authing.cn,不带最后的斜线 '/'。 */ appHost?: string; /** 应用密钥 */ secret?: string; /** 应用身份协议 */ protocol?: 'oauth' | 'oidc' | 'saml' | 'cas'; /** 获取 token 端点认证方式 */ tokenEndPointAuthMethod?: | 'client_secret_post' | 'client_secret_basic' | 'none'; /** 检查 token 端点认证方式 */ introspectionEndPointAuthMethod?: | 'client_secret_post' | 'client_secret_basic' | 'none'; /** 撤回 token 端点认证方式 */ revocationEndPointAuthMethod?: | 'client_secret_post' | 'client_secret_basic' | 'none'; /** 应用回调地址 */ redirectUri?: string; /** 请求超时时间 **/ timeout?: number; /** 错误回调函数, 默认为 (err: Error) => { throw err } 直接抛出报错 **/ onError?: (code: number, message: string, data?: any) => void; /** Websocket 服务器域名 */ websocketHost?: string; /** 请求来源 */ requestFrom?: string; /** token */ token?: string; /** 加密函数 */ encryptFunction?: ( plainText: string, publicKey: string, encryption?: Encryption ) => Promise; /** 密码传输加密公钥 */ publicKey?: string; httpClient?: typeof HttpClient; graphqlClient?: typeof GraphqlClient; tokenProvider?: typeof AuthenticationTokenProvider; /** 用于解密 Token 的私钥 */ privateKeys?: PrivateKey[]; /** * 语言 */ lang?: Lang; /** * @deprecated 该参数已经废弃,请使用 appHost */ host?: string; /** * @deprecated 该参数已经废弃,请使用 appHost */ domain?: string; /** * 请求头 key,适用于去 Authing 品牌化场景 */ headers?: { 'userpool-id': string; 'app-id': string; 'tenant-id'?: string; 'sdk-version': string; 'request-from': string; lang: string; }; encryption?: Encryption; // 事件订阅 socket 连接地址 socketUri?: string; // 重试次数 retryTimes?: number; } export interface QRCodeUserInfo { nickname: string; photo: string; id?: string; email?: string; emailVerified?: boolean; unionid?: string; openid?: string; oauth?: string; registerMethod?: string; username?: string; company?: string; token?: string; phone?: string; tokenExpiredAt?: string; loginsCount?: number; lastIP?: string; signedUp?: string; blocked?: boolean; isDeleted?: boolean; } export interface QRCodeStatus { random: string; /** 二维码状态: 0 - 未使用, 1 - 已扫码, 2 - 已授权, 3 - 取消授权, -1 - 已过期, 4 - 需要 MFA, 5 - 遇到错误 */ status: number; ticket?: string; userInfo?: QRCodeUserInfo; scannedResult?: Record; } export interface QRCodeGenarateResult { random: string; url: string; customLogo: string; } export type IMfaAuthenticators = Array<{ id: string; createdAt: string; updatedAt: string; userId: string; enable: boolean; secret: string; authenticatorType: string; recoveryCode: string; }>; export type IMfaAssociation = { authenticator_type: string; secret: string; // MFA Secret 可用于手动添加 MFA qrcode_uri: string; // MFA 二维码 Data Url,用于放在 src 中展示二维码 qrcode_data_url: string; // 恢复代码 recovery_code: string; }; export type IMfaConfirmAssociation = { code: number; message: string; }; export type IMfaDeleteAssociation = { code: number; message: string; }; /** * 密码安全等级 */ export enum PasswordSecurityLevel { LOW = 1, MIDDLE = 2, HIGH = 3 } export interface SecurityLevel { // 是否绑定了邮箱 email: boolean; // 是否绑定了个人 MFA mfa: boolean; // 是否设置了密码 password: boolean; // 是否绑定了手机号 phone: boolean; // 密码安全等级,null 表示密码还未做过安全等级检测检测 passwordSecurityLevel: PasswordSecurityLevel | null; // 账户的总体安全等级评分 score: number; } export enum SocialConnectionProvider { ALIPAY = 'alipay', GOOGLE = 'google', WECHATPC = 'wechat:pc', // 微信扫码登录 WECHATMP = 'wechat:webpage-authorization', // 微信公众号网页授权 WECHAT_MINIPROGRAM = 'wechat:miniprogram:default', // 微信小程序登录 WECHAT_MINIPROGRAM_QRCODE = 'wechat:miniprogram:qrconnect', // 微信小程序登录 WECHAT_MINIPROGRAM_APPLAUNCH = 'wechat:miniprogram:app-launch', // 微信小程序登录 WECHATMOBILE = 'wechat:mobile', // 微信移动应用 GITHUB = 'github', QQ = 'qq', WECHATWORK_ADDRESS_BOOK = 'wechatwork:addressbook', // 企业微信通讯录 WECHATWORK_CORP_QRCONNECT = 'wechatwork:corp:qrconnect', // 企业微信内部应用登录 WECHATWORK_SERVICEPROVIDER_QRCONNECT = 'wechatwork:service-provider:qrconnect', DINGTALK = 'dingtalk', WEIBO = 'weibo', APPLE = 'apple', APPLE_WEB = 'apple:web', LARK_PUBLIC = 'lark-public', LARK_INTERNAL = 'lark-internal', BAIDU = 'baidu', LINKEDIN = 'linkedin', SLACK = 'slack', YIDUN = 'yidun', QINGCLOUD = 'qingcloud', FACEBOOK = 'facebook' } export enum Protocol { OIDC = 'oidc', OAUTH = 'oauth', SAML = 'saml', CAS = 'cas', AZURE_AD = 'azure-ad' } export enum AppPasswordStrengthLimit { NoCheck, Low, Middle, High } export enum RegisterMethods { Email = 'email', Phone = 'phone' } export enum LoginMethods { LDAP = 'ldap', AppQr = 'app-qrcode', Password = 'password', PhoneCode = 'phone-code', WxMinQr = 'wechat-miniprogram-qrcode', // 对应社会化登录的 wechat:miniprogram:qrconnect(小程序扫码登录) AD = 'ad' // 对应企业身份源的 Windows AD 登录 } export interface IOAuthConnectionConfig { authEndPoint: string; tokenEndPoint: string; scope: string; clientId: string; clientSecret: string; authUrlTemplate: string; codeToTokenScript: string; tokenToUserInfoScript: string; tokenToUserInfoScriptFuncId: string; codeToTokenScriptFuncId: string; authUrl?: string; // 根据模板拼接出来的授权 url } export interface ISamlConnectionConfig { signInEndPoint: string; samlRequest?: string; // saml assertion 验签公钥 samlIdpCert: string; // saml request 验签公钥 samlSpCert: string; // saml request 签名私钥 samlSpKey: string; signOutEndPoint: string; signSamlRequest: boolean; signatureAlgorithm: string; digestAlgorithm: string; protocolBinding: string; } export interface ICasConnectionConfig { casConnectionLoginUrl: string; } export enum OIDCConnectionMode { FRONT_CHANNEL = 'FRONT_CHANNEL', BACK_CHANNEL = 'BACK_CHANNEL' } export interface IAzureAdConnectionConfig { microsoftAzureAdDomain: string; clientId: string; syncUserProfileOnLogin: string; emailVerifiedDefault: boolean; authorizationUrl: string; callbackUrl: string; } export interface OIDCConnectionConfig { issuerUrl: string; authorizationEdpoint: string; responseType: string; mode: OIDCConnectionMode; clientId: string; clientSecret: string; scopes: string; redirectUri: string; } export interface ApplicationConfig { id: string; cdnBase: string; userPoolId: string; rootUserPoolId: string; publicKey: string; passwordStrength: AppPasswordStrengthLimit; // 登录框自定义 css 代码 css: string; name: string; logo: string; redirectUris: string[]; registerDisabled: boolean; registerTabs: { list: RegisterMethods[]; default: string; title: { [x: string]: string }; }; loginTabs: { list: LoginMethods[]; default: string; title: { [x: string]: string }; }; socialConnections: { provider: string; name: string; authorizationUrl: string; }[]; agreementEnabled: boolean; extendsFieldsEnabled: boolean; identityProviders: { identifier: string; protocol: Protocol; displayName: string; logo: string; config: | ISamlConnectionConfig | OIDCConnectionConfig | ICasConnectionConfig | IAzureAdConnectionConfig | IOAuthConnectionConfig; }[]; ssoPageComponentDisplay: { autoRegisterThenLoginHintInfo: boolean; forgetPasswordBtn: boolean; idpBtns: boolean; loginBtn: boolean; loginByPhoneCodeTab: boolean; loginByUserPasswordTab: boolean; loginMethodNav: boolean; phoneCodeInput: boolean; registerBtn: boolean; registerByEmailTab: boolean; registerByPhoneTab: boolean; registerMethodNav: boolean; socialLoginBtns: boolean; userPasswordInput: boolean; wxMpScanTab: boolean; }; protocol: Protocol; oidcConfig: OidcClientMetadata; enableSubAccount: boolean; // 用户池是否在白名单 userPoolInWhitelist: boolean; userPortal: UserPortalConfig; /** websocket 域名*/ websocket: string; verifyCodeLength: number; } export interface OidcClientMetadata { grant_types: string[]; client_id: string; redirect_uris: string[]; scope: string; response_types: ResponseType[]; } export interface UserPortalConfig { cdnBase: string; assetsBase: string; assetsVersion: string; // 网站备案号 icpRecord: string; // 公安备案号 psbRecord: string; } export interface IOidcParams { appId?: string; redirectUri?: string; responseType?: | 'code' | 'code id_token token' | 'code id_token' | 'code token' | 'id_token token' | 'id_token' | 'none'; responseMode?: 'query' | 'fragment' | 'form_post'; state?: string; nonce?: string; scope?: string; codeChallengeMethod?: 'plain' | 'S256'; codeChallenge?: string; tenantId?: string; } export interface IOauthParams { appId?: string; redirectUri?: string; responseType?: 'code' | 'token'; state?: string; scope?: string; } export interface ILogoutParams { expert?: boolean; redirectUri?: string; idToken?: string; } export interface ICasParams { service?: string; } export type TotpSource = 'APPLICATION' | 'SELF'; export type ProviderType = | 'wechat:pc' | 'github' | 'google' | 'qq' | 'apple' | 'baidu' | 'alipay' | 'lark:app-store' | 'lark:custom-app' | 'weibo' | 'dingtalk' | 'wechat:webpage-authorization' | 'alipay' | 'wechat:miniprogram:default' | 'wechat:mobile' | 'wechatwork:service-provider:authorization' | 'wechatwork:service-provider:qrconnect' | 'wechatwork:corp:qrconnect' | 'wechat:miniprogram:app-launch' | 'wechat:miniprogram:qrconnect'; /** * 实体认证类型 * * P:个人认证 * E:企业认证 */ export type PrincipalType = 'P' | 'E'; export interface PrincipalDetail { authenticationTime: string; createdAt: string; id: string; principalCode: string; principalName: string; principalType: PrincipalType; updatedAt: string; userId: string; userPoolId: string; } export type PrincipalInput = | { /** 认证类型 */ type: 'P'; /** 姓名 */ name: string; /** 身份证 */ idCard: string; /** 银行卡号 */ bankCard: string; } | { /** 认证类型 */ type: 'E'; /** 企业名称 */ enterpriseName: string; /** 统一社会信用代码/注册号/组织机构代码 */ enterpriseCode: string; /** 企业法人名称 */ legalPersonName: string; }; export type Cas20ValidationSuccessResult = { serviceResponse: { authenticationSuccess: { user: string; attributes: { updated_at: string; address: { country: string; postal_code: string; region: string; formatted: string; }; phone_number_verified: boolean; phone_number: string; locale: string; zoneinfo: string; birthdate: string; gender: string; email_verified: boolean; email: string; website: string; picture: string; profile: string; preferred_username: string; nickname: string; middle_name: string; family_name: string; given_name: string; name: string; sub: string; external_id: string; unionid: string; }; }; }; }; export type Cas20ValidationFailureResult = { authenticationFailure: { code: string; description: string; }; }; export interface SsoSession { _id: string; cookie: { originalMaxAge: number; expires: string; secure: boolean; httpOnly: boolean; path: string; sameSite: string; appId: string; type: string; userId: string; }; } export interface PrivateKey { pkcs8Key: string; alg: 'RSA-OAEP' | 'ECDH-ES'; kid?: string; } export enum SceneType { SCENE_TYPE_LOGIN = 'login', SCENE_TYPE_REGISTER = 'register', SCENE_TYPE_RESET = 'reset', SCENE_TYPE_BIND = 'bind', SCENE_TYPE_UNBIND = 'unbind', SCENE_TYPE_MFA_BIND = 'mfa-bind', SCENE_TYPE_MFA_VERIFY = 'mfa-verify', SCENE_TYPE_MFA_UNBIND = 'mfa-unbind', SCENE_TYPE_COMPLETE_PHONE = 'complete-phone' } export enum RelayMethodEnum { WEB_MESSAGE = 'web_message', // 向父窗口发送 post message FORM_POST = 'form_post', // 用自动提交表单将客户端重定向到 target,表单中携带用户信息 QUERY = 'query' // 302 将客户端重定向到 target,查询参数携带用户信息(风变科技需求,向前兼容 callback url 参数用) } // 用户侧 列表 export interface MyDevicesList { device?: any; lastIp: string; lastLoginTime: string; online: boolean; } export enum SigninByCredentialsConnection { PASSWORD = 'PASSWORD', PASSCODE = 'PASSCODE', LDAP = 'LDAP', AD = 'AD' } export enum PasswordEncryptType { SM2 = 'sm2', RSA = 'rsa', NONE = 'none' } export interface SignInByPasswordPayloadDto { /** * 用户密码,默认不加密。Authing 所有 API 均通过 HTTPS 协议对密码进行安全传输,可以在一定程度上保证安全性。 * 如果你还需要更高级别的安全性,我们还支持 `RSA256` 和国密 `SM2` 的密码加密方式。详情见可选参数 `options.passwordEncryptType`。 * */ password: string; /** * 用户账号(用户名/手机号/邮箱) */ account?: string; /** * 邮箱,不区分大小写。 */ email?: string; /** * 用户名(username) */ username?: string; /** * 手机号 */ phone?: string; } export interface SignInByPassCodePayloadDto { /** * 一次性临时验证码,你需要先调用发送短信或者发送邮件接口获取验证码。 */ passCode: string; /** * 邮箱,不区分大小写。 */ email?: string; /** * 手机号 */ phone?: string; /** * 手机区号,中国大陆手机号可不填。Authing 短信服务暂不内置支持国际手机号,你需要在 Authing 控制台配置对应的国际短信服务。完整的手机区号列表可参阅 https://en.wikipedia.org/wiki/List_of_country_calling_codes。 */ phoneCountryCode?: string; } export interface SignInByAdPayloadDto { /** * 用户密码,默认不加密。Authing 所有 API 均通过 HTTPS 协议对密码进行安全传输,可以在一定程度上保证安全性。 * 如果你还需要更高级别的安全性,我们还支持 `RSA256` 和国密 `SM2` 的密码加密方式。详情见可选参数 `options.passwordEncryptType`。 * */ password: string; /** * Windows AD 用户目录中账号的 sAMAccountName */ sAMAccountName: string; } export interface SignInByLdapPayloadDto { /** * 用户密码,默认不加密。Authing 所有 API 均通过 HTTPS 协议对密码进行安全传输,可以在一定程度上保证安全性。 * 如果你还需要更高级别的安全性,我们还支持 `RSA256` 和国密 `SM2` 的密码加密方式。详情见可选参数 `options.passwordEncryptType`。 * */ password: string; /** * LDAP AD 用户目录中账号的 sAMAccountName */ sAMAccountName: string; } export enum SignInResponseType { IdTokenToken = 'id_token token', Code = 'code' } export interface SignInOptionsDto { /** * 需要请求的权限,必须包含 openid。如果需要获取手机号和 email 需要包含 phone email;如果需要 refresh_token 需要包含 offline_access。多个 scope 请用空格分隔。id_token 解码后的内容中会包含这些 scope 对应的用户信息相关的字段。 * - `openid`: 必须包含。 * - `profile`: 返回 birthdate,family_name,gender,given_name,locale,middle_name,name,nickname,picture,preferred_username,profile,updated_at,website,zoneinfo 字段。 * - `username`: 返回 username。 * - `email`: 返回 email,email_verified。 * - `phone`: 返回 phone_number, phone_number_verified。 * - `offline_access`: 如果存在此参数,token 接口会返回 refresh_token 字段。 * - `roles`: 返回用户的角色列表。 * - `external_id`: 用户在原有系统的用户 ID。 * - `extended_fields`: 返回用户的扩展字段信息,内容为一个对象,key 为扩展字段名,value 为扩展字段值。 * - `tenant_id`: 返回用户的租户 ID。 * */ scope?: string; /** * 客户端真实 IP 地址。默认情况下,Authing 会将请求来源的 IP 识别为用户登录的 IP 地址,如果你在后端服务器中调用此接口,需要将此 IP 设置为用户的真实请求 IP。 */ clientIp?: string; /** * 额外请求上下文,将会传递到认证前和认证后的 [Pipeline](https://docs.authing.cn/v2/guides/pipeline/) 的 `context` 对象中。了解[如何在 Pipeline 的 `context` 参数中获取传入的额外 context](https://docs.authing.cn/v2/guides/pipeline/context-object.html)。 */ context?: any; /** * 租户 ID */ tenantId?: string; /** * 设置额外的用户自定义数据,你需要先在 Authing 控制台[配置自定义数据](https://docs.authing.cn/v2/guides/users/user-defined-field/)。 */ customData?: any; /** * 是否开启自动注册。如果设置为 true,当用户不存在的时候,会先自动为其创建一个账号。注意:此参数只针对指定的用户名密码、邮箱密码、手机号密码有效,通用的账号密码不能设置此参数。 */ autoRegister?: boolean; /** * Captcha 图形验证码,不区分大小写。当**安全策略**设置为**验证码**且触发**登录失败次数限制**时,下次登录需要填写图形验证码。 */ captchaCode?: string; /** * /api/v3/get-captcha-code 获取 Captcha 图形验证码时,对应返回的 token,当传入 captchaCode 时,此参数必传 */ captchaToken?: string; /** * 密码加密类型,支持使用 RSA256 和国密 SM2 算法进行加密。默认为 `none` 不加密。 * - `none`: 不对密码进行加密,使用明文进行传输。 * - `rsa`: 使用 RSA256 算法对密码进行加密,需要使用 Authing 服务的 RSA 公钥进行加密,请阅读**介绍**部分了解如何获取 Authing 服务的 RSA256 公钥。 * - `sm2`: 使用 [国密 SM2 算法](https://baike.baidu.com/item/SM2/15081831) 对密码进行加密,需要使用 Authing 服务的 SM2 公钥进行加密,请阅读**介绍**部分了解如何获取 Authing 服务的 SM2 公钥。 * */ passwordEncryptType?: PasswordEncryptType; /** * 返回结果类型 * */ responseType?: SignInResponseType; /** * OIDC 登录重定向地址,当 `responseType` 为 `code` 时必传 * */ redirectUri?: string; /** * 当 responseType 是 code 时,是否自动跳转到回调地址 */ autoRedirect?: boolean; /** * 当 autoRedirect 为 true,跳转到回调地址的 state 参数,如果不传会自动生成 */ state?: string; /** * OIDC id_token 的 nonce 参数 */ nonce?: string; } export interface SigninByCredentialsDto { /** * 认证方式: * - `PASSWORD`: 使用密码方式进行认证。 * - `PASSCODE`: 使用一次性临时验证码进行认证。 * - `LDAP`: 基于 LDAP 用户目录进行认证。 * - `AD`: 基于 Windows AD 用户目录进行认证。 * */ connection: SigninByCredentialsConnection; /** * 当认证方式为 `PASSWORD` 时此参数必填。 */ passwordPayload?: SignInByPasswordPayloadDto; /** * 当认证方式为 `PASSCODE` 时此参数必填 */ passCodePayload?: SignInByPassCodePayloadDto; /** * 当认证方式为 `AD` 时此参数必填 */ adPayload?: SignInByAdPayloadDto; /** * 当认证方式为 `LDAP` 时此参数必填 */ ldapPayload?: SignInByLdapPayloadDto; /** * 可选参数 */ options?: SignInOptionsDto; /** * 应用 ID。当应用的「换取 token 身份验证方式」配置为 `client_secret_post` 需要传。 */ client_id?: string; /** * 应用密钥。当应用的「换取 token 身份验证方式」配置为 `client_secret_post` 需要传。 */ client_secret?: string; }