Skip to content
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
18 changes: 18 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { fixupConfigRules } from '@eslint/compat';
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import prettier from 'eslint-plugin-prettier';
import tseslint from 'typescript-eslint';
import { defineConfig } from 'eslint/config';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
Expand Down Expand Up @@ -32,6 +33,23 @@ export default defineConfig([
],
},
},
// TypeScript-specific configuration for type-checked rules
{
files: ['**/*.ts', '**/*.tsx'],
ignores: ['**/__tests__/**', '**/__mocks__/**', '**/*.spec.ts', '**/*.spec.tsx', '**/*.test.ts', '**/*.test.tsx'],
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// Enable unbound-method rule to catch interface typing issues
// This helps ensure methods in interfaces use arrow function syntax
// instead of method syntax when they don't use 'this'
'@typescript-eslint/unbound-method': 'error',
},
},
{
ignores: ['node_modules/', 'lib/', 'docs'],
},
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@
"typedoc": "^0.28.2",
"typedoc-plugin-missing-exports": "^4.0.0",
"typedoc-plugin-replace-text": "^4.2.0",
"typescript": "5.2.2"
"typescript": "5.2.2",
"typescript-eslint": "^8.46.2"
},
"dependencies": {
"@auth0/auth0-spa-js": "2.7.0",
Expand Down
62 changes: 34 additions & 28 deletions src/hooks/Auth0Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ export interface Auth0ContextInterface extends AuthState {
* @returns A promise that resolves with the user's credentials upon successful authentication.
* @throws {AuthError} If the authentication fails.
*/
authorize(
authorize: (
parameters?: WebAuthorizeParameters,
options?: NativeAuthorizeOptions
): Promise<Credentials>;
) => Promise<Credentials>;

/**
* Clears the user's session and logs them out.
Expand All @@ -51,18 +51,18 @@ export interface Auth0ContextInterface extends AuthState {
* @returns A promise that resolves when the session has been cleared.
* @throws {AuthError} If the logout fails.
*/
clearSession(
clearSession: (
parameters?: ClearSessionParameters,
options?: NativeClearSessionOptions
): Promise<void>;
) => Promise<void>;

/**
* Saves the user's credentials.
* @param credentials The credentials to save.
* @returns A promise that resolves when the credentials have been saved.
* @throws {AuthError} If the save fails.
*/
saveCredentials(credentials: Credentials): Promise<void>;
saveCredentials: (credentials: Credentials) => Promise<void>;

/**
* Retrieves the stored credentials, refreshing them if necessary.
Expand All @@ -73,12 +73,12 @@ export interface Auth0ContextInterface extends AuthState {
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If credentials cannot be retrieved or refreshed.
*/
getCredentials(
getCredentials: (
scope?: string,
minTtl?: number,
parameters?: Record<string, unknown>,
forceRefresh?: boolean
): Promise<Credentials>;
) => Promise<Credentials>;

/**
* Clears the user's credentials without clearing their web session and logs them out.
Expand All @@ -96,13 +96,13 @@ export interface Auth0ContextInterface extends AuthState {
* @param minTtl The minimum time-to-live (in seconds) required for the access token to be considered valid. Defaults to 0.
* @returns A promise that resolves with `true` if valid credentials exist, `false` otherwise.
*/
hasValidCredentials(minTtl?: number): Promise<boolean>;
hasValidCredentials: (minTtl?: number) => Promise<boolean>;

/**
* Cancels the ongoing web authentication process.
* This works only on iOS. On other platforms, it will resolve without performing an action.
*/
cancelWebAuth(): Promise<void>;
cancelWebAuth: () => Promise<void>;

/**
* Authenticates a user with their username and password.
Expand All @@ -111,25 +111,25 @@ export interface Auth0ContextInterface extends AuthState {
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the authentication fails.
*/
loginWithPasswordRealm(
loginWithPasswordRealm: (
parameters: PasswordRealmParameters
): Promise<Credentials>;
) => Promise<Credentials>;

/**
* Creates a new user in a database connection.
* @param parameters The parameters for creating the new user.
* @returns A promise that resolves with the new user's profile information.
* @throws {AuthError} If the user creation fails.
*/
createUser(parameters: CreateUserParameters): Promise<Partial<User>>;
createUser: (parameters: CreateUserParameters) => Promise<Partial<User>>;

/**
* Resets the user's password.
* @param parameters The parameters for resetting the password.
* @returns A promise that resolves when the password has been reset.
* @throws {AuthError} If the reset fails.
*/
resetPassword(parameters: ResetPasswordParameters): Promise<void>;
resetPassword: (parameters: ResetPasswordParameters) => Promise<void>;

/**
* Exchanges an authorization code for tokens.
Expand All @@ -138,87 +138,91 @@ export interface Auth0ContextInterface extends AuthState {
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the exchange fails.
*/
authorizeWithExchange(parameters: ExchangeParameters): Promise<Credentials>;
authorizeWithExchange: (
parameters: ExchangeParameters
) => Promise<Credentials>;

/**
* Exchanges an authorization code for native social tokens.
* @param parameters The parameters containing the authorization code and verifier.
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the exchange fails.
*/
authorizeWithExchangeNativeSocial(
authorizeWithExchangeNativeSocial: (
parameters: ExchangeNativeSocialParameters
): Promise<Credentials>;
) => Promise<Credentials>;

/**
* Sends a verification code to the user's email.
* @param parameters The parameters for sending the email code.
* @throws {AuthError} If sending the email code fails.
*/
sendEmailCode(parameters: PasswordlessEmailParameters): Promise<void>;
sendEmailCode: (parameters: PasswordlessEmailParameters) => Promise<void>;

/**
* Authorizes a user with their email.
* @param parameters The parameters for email authorization.
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the authorization fails.
*/
authorizeWithEmail(parameters: LoginEmailParameters): Promise<Credentials>;
authorizeWithEmail: (
parameters: LoginEmailParameters
) => Promise<Credentials>;

/**
/**
* Sends a verification code to the user's SMS.
* @param parameters The parameters for sending the SMS code.
* @throws {AuthError} If sending the SMS code fails.
*/
sendSMSCode(parameters: PasswordlessSmsParameters): Promise<void>;
sendSMSCode: (parameters: PasswordlessSmsParameters) => Promise<void>;

/**
* Authorizes a user with their SMS.
* @param parameters The parameters for SMS authorization.
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the authorization fails.
*/
authorizeWithSMS(parameters: LoginSmsParameters): Promise<Credentials>;
authorizeWithSMS: (parameters: LoginSmsParameters) => Promise<Credentials>;

/**
* Sends a multifactor challenge to the user.
* @param parameters The parameters for the multifactor challenge.
* @returns A promise that resolves when the challenge has been sent.
* @throws {AuthError} If sending the challenge fails.
*/
sendMultifactorChallenge(
sendMultifactorChallenge: (
parameters: MfaChallengeParameters
): Promise<MfaChallengeResponse>;
) => Promise<MfaChallengeResponse>;

/**
* Authorizes a user with out-of-band (OOB) authentication.
* @param parameters The parameters for OOB authorization.
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the authorization fails.
*/
authorizeWithOOB(parameters: LoginOobParameters): Promise<Credentials>;
authorizeWithOOB: (parameters: LoginOobParameters) => Promise<Credentials>;

/**
* Authorizes a user with a one-time password (OTP).
* @param parameters The parameters for OTP authorization.
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the authorization fails.
*/
authorizeWithOTP(parameters: LoginOtpParameters): Promise<Credentials>;
authorizeWithOTP: (parameters: LoginOtpParameters) => Promise<Credentials>;

/**
* Authorizes a user with a recovery code.
* @param parameters The parameters for recovery code authorization.
* @returns A promise that resolves with the user's credentials.
* @throws {AuthError} If the authorization fails.
*/
authorizeWithRecoveryCode(
authorizeWithRecoveryCode: (
parameters: LoginRecoveryCodeParameters
): Promise<Credentials>;
) => Promise<Credentials>;

// Token Management
revokeRefreshToken(parameters: RevokeOptions): Promise<void>;
revokeRefreshToken: (parameters: RevokeOptions) => Promise<void>;

/**
* Generates DPoP headers for making authenticated requests to custom APIs.
Expand All @@ -244,7 +248,9 @@ export interface Auth0ContextInterface extends AuthState {
* }
* ```
*/
getDPoPHeaders(params: DPoPHeadersParams): Promise<Record<string, string>>;
getDPoPHeaders: (
params: DPoPHeadersParams
) => Promise<Record<string, string>>;
}

const stub = (): any => {
Expand Down
45 changes: 32 additions & 13 deletions src/platforms/native/bridge/NativeBridgeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ export class NativeBridgeManager implements INativeBridge {

async hasValidInstance(clientId: string, domain: string): Promise<boolean> {
return this.a0_call(
Auth0NativeModule.hasValidAuth0InstanceWithConfiguration,
Auth0NativeModule.hasValidAuth0InstanceWithConfiguration.bind(
Auth0NativeModule
),
clientId,
domain
);
Expand All @@ -55,7 +57,9 @@ export class NativeBridgeManager implements INativeBridge {
// This is a new method we'd add to the native side to ensure the
// underlying Auth0.swift/Auth0.android SDKs are configured.
return this.a0_call(
Auth0NativeModule.initializeAuth0WithConfiguration,
Auth0NativeModule.initializeAuth0WithConfiguration.bind(
Auth0NativeModule
),
clientId,
domain,
localAuthenticationOptions,
Expand All @@ -64,7 +68,9 @@ export class NativeBridgeManager implements INativeBridge {
}

getBundleIdentifier(): Promise<string> {
return this.a0_call(Auth0NativeModule.getBundleIdentifier);
return this.a0_call(
Auth0NativeModule.getBundleIdentifier.bind(Auth0NativeModule)
);
}

async authorize(
Expand All @@ -79,7 +85,7 @@ export class NativeBridgeManager implements INativeBridge {
const scheme =
parameters.redirectUrl?.split('://')[0] ?? options.customScheme;
const credential = await this.a0_call(
Auth0NativeModule.webAuth,
Auth0NativeModule.webAuth.bind(Auth0NativeModule),
scheme,
parameters.redirectUrl,
parameters.state,
Expand All @@ -104,19 +110,24 @@ export class NativeBridgeManager implements INativeBridge {
options: NativeClearSessionOptions
): Promise<void> {
return this.a0_call(
Auth0NativeModule.webAuthLogout,
Auth0NativeModule.webAuthLogout.bind(Auth0NativeModule),
options.customScheme,
parameters.federated ?? false,
parameters.returnToUrl
);
}

async cancelWebAuth(): Promise<void> {
return this.a0_call(Auth0NativeModule.cancelWebAuth);
return this.a0_call(
Auth0NativeModule.cancelWebAuth.bind(Auth0NativeModule)
);
}

async saveCredentials(credentials: Credentials): Promise<void> {
return this.a0_call(Auth0NativeModule.saveCredentials, credentials);
return this.a0_call(
Auth0NativeModule.saveCredentials.bind(Auth0NativeModule),
credentials
);
}

async getCredentials(
Expand All @@ -128,7 +139,7 @@ export class NativeBridgeManager implements INativeBridge {
// Assuming the native side can take an empty object for parameters.
const params = parameters ?? {};
return this.a0_call(
Auth0NativeModule.getCredentials,
Auth0NativeModule.getCredentials.bind(Auth0NativeModule),
scope,
minTtl ?? 0,
params,
Expand All @@ -137,22 +148,30 @@ export class NativeBridgeManager implements INativeBridge {
}

async hasValidCredentials(minTtl?: number): Promise<boolean> {
return this.a0_call(Auth0NativeModule.hasValidCredentials, minTtl ?? 0);
return this.a0_call(
Auth0NativeModule.hasValidCredentials.bind(Auth0NativeModule),
minTtl ?? 0
);
}

async clearCredentials(): Promise<void> {
return this.a0_call(Auth0NativeModule.clearCredentials);
return this.a0_call(
Auth0NativeModule.clearCredentials.bind(Auth0NativeModule)
);
}

async resumeWebAuth(url: string): Promise<void> {
return this.a0_call(Auth0NativeModule.resumeWebAuth, url);
return this.a0_call(
Auth0NativeModule.resumeWebAuth.bind(Auth0NativeModule),
url
);
}

async getDPoPHeaders(
params: DPoPHeadersParams
): Promise<Record<string, string>> {
return this.a0_call(
Auth0NativeModule.getDPoPHeaders,
Auth0NativeModule.getDPoPHeaders.bind(Auth0NativeModule),
params.url,
params.method,
params.accessToken,
Expand All @@ -162,6 +181,6 @@ export class NativeBridgeManager implements INativeBridge {
}

async clearDPoPKey(): Promise<void> {
return this.a0_call(Auth0NativeModule.clearDPoPKey);
return this.a0_call(Auth0NativeModule.clearDPoPKey.bind(Auth0NativeModule));
}
}
Loading