Skip to content

Commit

Permalink
adding comments
Browse files Browse the repository at this point in the history
  • Loading branch information
pragatimodi committed Oct 18, 2023
1 parent dfe7f4a commit abfb295
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 40 deletions.
21 changes: 3 additions & 18 deletions etc/firebase-admin.auth.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,38 +345,23 @@ export interface OIDCUpdateAuthProviderRequest {
responseType?: OAuthResponseType;
}

// @public (undocumented)
// @public
export class PasskeyConfig {
// Warning: (ae-forgotten-export) The symbol "PasskeyConfigServerResponse" needs to be exported by the entry point index.d.ts
constructor(response: PasskeyConfigServerResponse);
// Warning: (ae-forgotten-export) The symbol "PasskeyConfigClientRequest" needs to be exported by the entry point index.d.ts
//
// (undocumented)
static buildServerRequest(isCreateRequest: boolean, passkeyConfigRequest?: PasskeyConfigRequest, rpId?: string): PasskeyConfigClientRequest;
// (undocumented)
readonly expectedOrigins?: string[];
// (undocumented)
readonly name?: string;
// (undocumented)
readonly rpId?: string;
// (undocumented)
toJSON(): object;
}

// @public (undocumented)
// @public
export class PasskeyConfigManager {
constructor(app: App);
// (undocumented)
createPasskeyConfig(rpId: string, passkeyConfigRequest: PasskeyConfigRequest, tenantId?: string): Promise<PasskeyConfig>;
// (undocumented)
getPasskeyConfig(tenantId?: string): Promise<PasskeyConfig>;
// (undocumented)
updatePasskeyConfig(passkeyConfigRequest: PasskeyConfigRequest, tenantId?: string): Promise<PasskeyConfig>;
}

// @public (undocumented)
// @public
export interface PasskeyConfigRequest {
// (undocumented)
expectedOrigins?: string[];
}

Expand Down
24 changes: 12 additions & 12 deletions src/auth/auth-api-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2071,51 +2071,51 @@ const CREATE_TENANT = new ApiSettings('/tenants', 'POST')
}
});

/** Instantiates the getPasskeyConfig endpoint settings. */
/** Instantiates the GET_PASSKEY_CONFIG endpoint settings. */
const GET_PASSKEY_CONFIG = new ApiSettings('/passkeyConfig', 'GET')
.setResponseValidator((response: any) => {
// Response should always contain at least the config name.
// Validate the response for GET_PASSKEY_CONFIG.
if (!validator.isNonEmptyString(response.name)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INTERNAL_ERROR,
'INTERNAL ASSERT FAILED: Unable to get project config',
'INTERNAL ASSERT FAILED: Unable to get passkey config',
);
}
});

/** Instantiates the getPasskeyConfig endpoint settings. */
/** Instantiates the GET_TENANT_PASSKEY_CONFIG endpoint settings. */
const GET_TENANT_PASSKEY_CONFIG = new ApiSettings('/tenants/{tenantId}/passkeyConfig', 'GET')
.setResponseValidator((response: any) => {
// Response should always contain at least the config name.
// Validate the response for GET_TENANT_PASSKEY_CONFIG.
if (!validator.isNonEmptyString(response.name)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INTERNAL_ERROR,
'INTERNAL ASSERT FAILED: Unable to get project config',
'INTERNAL ASSERT FAILED: Unable to get tenant passkey config',
);
}
});

/** Instantiates the getPasskeyConfig endpoint settings. */
/** Instantiates the UPDATE_PASSKEY_CONFIG endpoint settings. */
const UPDATE_PASSKEY_CONFIG = new ApiSettings('/passkeyConfig?updateMask={updateMask}', 'PATCH')
.setResponseValidator((response: any) => {
// Response should always contain at least the config name.
// Validate the response for UPDATE_PASSKEY_CONFIG.
if (!validator.isNonEmptyString(response.name)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INTERNAL_ERROR,
'INTERNAL ASSERT FAILED: Unable to get project config',
'INTERNAL ASSERT FAILED: Unable to update passkey config',
);
}
});

/** Instantiates the getPasskeyConfig endpoint settings. */
/** Instantiates the UPDATE_TENANT_PASSKEY_CONFIG endpoint settings. */
const UPDATE_TENANT_PASSKEY_CONFIG = new ApiSettings(
'/tenant/{tenantId}/passkeyConfig?updateMask={updateMask}', 'PATCH')
.setResponseValidator((response: any) => {
// Response should always contain at least the config name.
// Validate the response for UPDATE_TENANT_PASSKEY_CONFIG.
if (!validator.isNonEmptyString(response.name)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INTERNAL_ERROR,
'INTERNAL ASSERT FAILED: Unable to get project config',
'INTERNAL ASSERT FAILED: Unable to update tenant passkey config',
);
}
});
Expand Down
33 changes: 32 additions & 1 deletion src/auth/passkey-config-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,45 @@ import {
PasskeyConfigServerResponse
} from './passkey-config';


/**
* Manages Passkey Configuration for a Firebase app.
*/
export class PasskeyConfigManager {
private readonly authRequestHandler: AuthRequestHandler;

/**
* Initializes a PasskeyConfigManager instance for a specified FirebaseApp.
*
* @param app - The Firebase app associated with this PasskeyConfigManager instance.
*
* @constructor
* @internal
*/
constructor(app: App) {
this.authRequestHandler = new AuthRequestHandler(app);
}

/**
* Retrieves the Passkey Configuration.
*
* @param tenantId - (optional) The tenant ID if querying passkeys on a specific tenant.
* @returns A promise fulfilled with the passkey configuration.
*/
public getPasskeyConfig(tenantId?: string): Promise<PasskeyConfig> {
return this.authRequestHandler.getPasskeyConfig(tenantId)
.then((response: PasskeyConfigServerResponse) => {
return new PasskeyConfig(response);
});
}

/**
* Creates a new passkey configuration.
*
* @param rpId - The relying party ID.
* @param passkeyConfigRequest - Configuration details for the passkey.
* @param tenantId - (optional) The tenant ID for which the passkey config is created.
* @returns A promise fulfilled with the newly created passkey configuration.
*/
public createPasskeyConfig(rpId: string, passkeyConfigRequest: PasskeyConfigRequest,
tenantId?: string): Promise<PasskeyConfig> {
return this.authRequestHandler.updatePasskeyConfig(true, tenantId, passkeyConfigRequest, rpId)
Expand All @@ -47,6 +71,13 @@ export class PasskeyConfigManager {
});
}

/**
* Updates an existing passkey configuration.
*
* @param passkeyConfigRequest - Updated configuration details for the passkey.
* @param tenantId - (optional) The tenant ID for which the passkey config is updated.
* @returns A promise fulfilled with the updated passkey configuration.
*/
public updatePasskeyConfig(passkeyConfigRequest: PasskeyConfigRequest, tenantId?: string): Promise<PasskeyConfig> {
return this.authRequestHandler.updatePasskeyConfig(false, tenantId, passkeyConfigRequest)
.then((response: PasskeyConfigClientRequest) => {
Expand Down
74 changes: 65 additions & 9 deletions src/auth/passkey-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,87 @@ import * as validator from '../utils/validator';
import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error';
import { deepCopy } from '../utils/deep-copy';

/**
* Interface representing the properties to update in the provided passkey config.
*/
export interface PasskeyConfigRequest {
/**
* An array of website or app origins associated with the customer's sites or apps.
* Only challenges signed from these origins will be allowed for signing in with passkeys.
*/
expectedOrigins?: string[];
}

/**
* Response received from the server when retrieving, creating, or updating the passkey config.
*/
export interface PasskeyConfigServerResponse {
name?: string;
rpId?: string;
expectedOrigins?: string[];
}

/**
* Request for creating or updating the passkey config on the server.
*/
export interface PasskeyConfigClientRequest {
rpId?: string;
expectedOrigins?: string[];
}


/**
* Configuration for signing in users using passkeys.
*/
export class PasskeyConfig {
/**
* The name of the PasskeyConfig resource.
*/
public readonly name?: string;
/**
* The relying party ID for passkey verifications.
* This cannot be changed once created.
*/
public readonly rpId?: string;
/**
* The website or app origins associated with the customer's sites or apps.
* Only challenges signed from these origins will be allowed for signing in with passkeys.
*/
public readonly expectedOrigins?: string[];

/**
* Validates a passkey config request object and throws an error on failure.
* @param isCreateRequest - A boolean indicating if it's a create request or not.
* @param passkeyConfigRequest - Passkey config to be set.
* @param rpId - (optional) Relying party ID if it's a create request.
* @throws FirebaseAuthError - If validation fails.
*
* @internal
*/
private static validate(isCreateRequest: boolean, passkeyConfigRequest?: PasskeyConfigRequest, rpId?: string): void {
// Validation for creating a new PasskeyConfig.
if (isCreateRequest && !validator.isNonEmptyString(rpId)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'\'rpId\' must be a valid non-empty string\'',
"'rpId' must be a valid non-empty string.",
);
}
// Validation for updating an existing PasskeyConfig.
if (!isCreateRequest && typeof rpId !== 'undefined') {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'\'rpId\' cannot be changed once created.\'',
"'rpId' cannot be changed once created.",
);
}
if (!validator.isNonNullObject(passkeyConfigRequest)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'\'passkeyConfigRequest\' must be a valid non-empty object.\'',
"'passkeyConfigRequest' must be a valid non-empty object.",
);
}
const validKeys = {
expectedOrigins: true,
};
// Check for unsupported top level attributes.
// Check for unsupported top-level attributes.
for (const key in passkeyConfigRequest) {
if (!(key in validKeys)) {
throw new FirebaseAuthError(
Expand All @@ -72,19 +109,29 @@ export class PasskeyConfig {
if (!validator.isNonEmptyArray(passkeyConfigRequest.expectedOrigins)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'\'passkeyConfigRequest.expectedOrigins\' must be a valid non-empty array of strings.\'',
"'passkeyConfigRequest.expectedOrigins' must be a valid non-empty array of strings.",
);
}
for (const origin of passkeyConfigRequest.expectedOrigins) {
if (!validator.isNonEmptyString(origin)) {
throw new FirebaseAuthError(
AuthClientErrorCode.INVALID_ARGUMENT,
'\'passkeyConfigRequest.expectedOrigins\' must be a valid non-empty array of strings.\'',
"'passkeyConfigRequest.expectedOrigins' must be a valid non-empty array of strings.",
);
}
}
}

/**
* Build the corresponding server request for a Passkey Config object.
* @param isCreateRequest - A boolean stating if it's a create request.
* @param passkeyConfigRequest - Passkey config to be updated.
* @param rpId - (optional) Relying party ID for the request if it's a create request.
* @returns The equivalent server request.
* @throws FirebaseAuthError - If validation fails.
*
* @internal
*/
public static buildServerRequest(isCreateRequest: boolean, passkeyConfigRequest?: PasskeyConfigRequest,
rpId?: string): PasskeyConfigClientRequest {
PasskeyConfig.validate(isCreateRequest, passkeyConfigRequest, rpId);
Expand All @@ -98,6 +145,13 @@ export class PasskeyConfig {
return request;
}

/**
* The Passkey Config object constructor.
* @param response - The server-side response used to initialize the Passkey Config object.
* @constructor
*
* @internal
*/
constructor(response: PasskeyConfigServerResponse) {
if (typeof response.name !== 'undefined') {
this.name = response.name;
Expand All @@ -110,6 +164,10 @@ export class PasskeyConfig {
}
}

/**
* Returns a JSON-serializable representation of this object.
* @returns A JSON-serializable representation of this object.
*/
public toJSON(): object {
const json = {
name: deepCopy(this.name),
Expand All @@ -127,6 +185,4 @@ export class PasskeyConfig {
}
return json;
}

}

0 comments on commit abfb295

Please sign in to comment.