Upgrade to v4

Breaking changes from PassageJS v3 to v4

TypeScript updates

Passage-JS v4 has a new type system that is more robust and aligned with TypeScript conventions. Most types returned by Passage-JS methods have been updated and renamed. Additionally all interface fields now consistently use camelCase instead of snake_case.

For example the updated PassageAppInfo type is:

interface PassageAppInfo {
    allowedIdentifier: string;
    authMethods: AuthMethods;
    authOrigin: string;
    defaultLanguage: string;
    elementCustomization: ElementCustomization;
    elementCustomizationDark: ElementCustomization;
    id: string;
    layouts: Layouts;
    loginUrl: string;
    name: string;
    passageBranding: boolean;
    publicSignup: boolean;
    profileManagement: boolean;
    redirectUrl: string;
    requireEmailVerification: boolean;
    requireIdentifierVerification: boolean;
    requiredIdentifier: string;
    rsaPublicKey: string;
    sessionTimeoutLength: number;
    socialConnections: SocialConnections;
    userMetadataSchema: Array<UserMetadataField>;
}

Method reorganization

Passage-JS v4 introduces a new class-based organization to the API that organizes methods into classes based on their functionality. When upgrading to v4 you will need to update your code to use the new class-based methods.

You can see the full Passage-JS v4 API reference can be found in the README of the NPM package @passageidentity/passage-js (opens in a new tab).

App methods

V3 methodV4 method

appInfo(): Promise<PassageAppInfo>

app.info(): Promise<PassageAppInfo>

identifierExists(identifier: string): Promise<PassageUser>

app.userExists(identifier: string): Promise<PublicUserInfo>

createUser(payload: CreateUserPayload): Promise<PassageUser>

app.createUser(identifier: string, userMetadata?: Metadata): Promise<PublicUserInfo>

Passkey methods

V3 methodV4 method

register(identifier: string, options?: PasskeyCreationOptions): Promise<authResult>

passkey.register(identifier: string, options?: PasskeyCreationOptions): Promise<AuthResult>;

login(identifier: string): Promise<authResult>

passkey.login(identifier?: string, options?: PasskeyLoginOptions): Promise<AuthResult>;

loginConditional(signal?: AbortSignal): Promise<authResult>

passkey.login(identifier?: string, options?: PasskeyLoginOptions): Promise<AuthResult>;

getCredentialAvailable(): Promise<IGetCredentialFeatures>

passkey.getCredentialAvailable(): Promise<IGetCredentialFeatures>

createCredentialAvailable(): Promise<ICreateCredentialFeatures>

passkey.createCredentialAvailable(): Promise<ICreateCredentialFeatures>

checkWebauthnConfig(appInfo: PassageAppInfo): boolean

passkey.checkPasskeyOrigin(): boolean

credIDExists(userID: string): boolean

passkey.hasLocalPasskey(userId: string): boolean

MagicLink methods

V3 methodV4 method

newRegisterMagicLink(identifier: string, language?: string): Promise<PassageMagicLinkRequest>

magicLink.register(identifier: string, language?: string): Promise<MagicLink>

newLoginMagicLink(identifier: string, language?: string): Promise<PassageMagicLinkRequest>

magicLink.login(identifier: string, language?: string): Promise<MagicLink>

magicLinkActivate(userMagicLink: string): Promise<authResult>

magicLink.activate(magicLink: string): Promise<AuthResult>

getMagicLinkStatus(id: string): Promise<authResult>

magicLink.status(id: string): Promise<AuthResult>

OneTimePasscode methods

V3 methodV4 method

newRegisterOneTimePasscode(identifier: string, language?: string): Promise<PassageOneTimePasscodeRequest>

oneTimePasscode.register(identifier: string, language?: string): Promise<OneTimePasscode>

newLoginOneTimePasscode(identifier: string, language?: string): Promise<PassageOneTimePasscodeRequest>

oneTimePasscode.login(identifier: string, language?: string): Promise<OneTimePasscode>

oneTimePasscodeActivate(otp: string, otpId: string): Promise<authResult>

oneTimePasscode.activate(oneTimePasscode: string, id: string): Promise<AuthResult>;

Social methods

V3 methodV4 method

authorizeWith(connection: SocialConnection): Promise<void>

social.authorize(connection: SocialConnection): Promise<void>

finishSocialAuthentication(code: string): Promise<authResult>

social.finish(code: string): Promise<AuthResult>

CurrentUser methods

The old currentUser methods were already in a CurrentUser class that was accessed through getCurrentUser(). In v4 the currentUser class in now accessed through the currentUser property on the main Passage class.

Some of the methods have updated types or have been renamed:

V3 methodV4 method

getCurrentUser(): User

currentUser: PassageCurrentUser

userInfo(): Promise<PassageUserInfo | undefined>

userInfo(): Promise<CurrentUser | undefined>

changeEmail(newEmail: string, language?: string): Promise<PassageMagicLinkRequest>

changeEmail(newEmail: string, language?: string): Promise<MagicLink>

changePhone(newPhone: string, language?: string): Promise<PassageMagicLinkRequest>

changePhone(newPhone: string, language?: string): Promise<MagicLink>

listDevices(): Promise<PassageDevice[]>

passkeys(): Promise<Passkey[]>;

editDevice(deviceID: string, editDeviceRequest: PassageEditDeviceRequest): Promise<PassageDevice>

editPasskey(passkeyId: string, friendlyName: string): Promise<Passkey>

addDevice(options?: PasskeyCreationOptions): Promise<PassageDevice>

addPasskey(options?: PasskeyCreationOptions): Promise<Passkey>

deleteDevice(deviceID: string | PassageDevice): Promise<boolean>

deletePasskey(passkey: Passkey): Promise<boolean>

listSocialConnections(): Promise<Record<SocialConnection, PassageUserSocialConnection>>

socialConnections(): Promise<UserSocialConnections>

Session methods

The Session class is unchanged from Passage-JS v3, however it was previously accessed through getCurrentSession() and is now accessed through the session property on the main Passage class.

V3 methodV4 property
getCurrentSession(): Sessionsession: PassageSession