[go: nahoru, domu]

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

Support MFA TOTP in web SDK #7146

Merged
merged 26 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ebbf397
adding support TOTP MFA (#6547)
bhparijat Aug 31, 2022
c79e7fb
Implement TOTP MFA enrollment flows (#6598)
prameshj Sep 14, 2022
e11ed0b
restore totp*.ts into mfa/assertions directory. (#6602)
prameshj Sep 16, 2022
524f1d1
Demo-app readme fix (#6630)
bhparijat Sep 28, 2022
b6c736f
Mfa totp demoapp (#6629)
prameshj Oct 5, 2022
e3f2bea
sign-in flow for totp (#6626)
bhparijat Oct 13, 2022
59e6da3
Unit test cases for sign-in flow (#6640)
bhparijat Oct 14, 2022
7310822
integration tests for totp (#6784)
bhparijat Nov 22, 2022
07eacac
Totp integration test fix (#6814)
bhparijat Dec 3, 2022
36fc7c7
fixing conflict in package.json (#6855)
bhparijat Dec 5, 2022
3c64cc7
Fix mfa totp unit test (#6858)
prameshj Dec 7, 2022
1fcf4e1
Added ui for setting tenant-id (#6850)
bhparijat Dec 7, 2022
5ff2929
Expose enrollmentCompletionDeadline field in TotpSecret. (#6870)
prameshj Dec 27, 2022
b00a7ae
clear TOTP QR code display in the demo app once enrollment is complet…
prameshj Jan 28, 2023
119cb1c
Add a command to run totp integration tests. (#6998)
prameshj Feb 15, 2023
522392a
remove startMfaSignIn step for TOTP. (#7047)
prameshj Feb 22, 2023
2ab3198
Add back totp-generator dep (removed during merge conflict)
prameshj Mar 22, 2023
df20c0a
Fix doc comments in TOTP files
prameshj Mar 28, 2023
0972c84
Generate docs for TOTP
prameshj Mar 28, 2023
b13870c
Add changeset
prameshj Mar 28, 2023
8c158e8
Update packages/auth/src/mfa/assertions/totp.ts
prameshj Mar 28, 2023
5e73e41
Update packages/auth/src/model/public_types.ts
prameshj Mar 28, 2023
be27f0b
Update packages/auth/src/mfa/assertions/totp.ts
prameshj Mar 28, 2023
81c3177
Update packages/auth/src/mfa/assertions/totp.ts
prameshj Mar 28, 2023
a507d93
Apply suggestions from code review
prameshj Mar 28, 2023
7c2af18
re-generate docs
prameshj Mar 28, 2023
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
5 changes: 5 additions & 0 deletions .changeset/hot-experts-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@firebase/auth': patch
---

Support TOTP as a multi-factor option in Firebase Auth/GCIP.
36 changes: 36 additions & 0 deletions common/api-review/auth.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ export class FacebookAuthProvider extends BaseOAuthProvider {
// @public
export const FactorId: {
readonly PHONE: "phone";
readonly TOTP: "totp";
};

// @public
Expand Down Expand Up @@ -745,6 +746,41 @@ export function signInWithRedirect(auth: Auth, provider: AuthProvider, resolver?
// @public
export function signOut(auth: Auth): Promise<void>;

// @public
export interface TotpMultiFactorAssertion extends MultiFactorAssertion {
}

// @public
export class TotpMultiFactorGenerator {
static assertionForEnrollment(secret: TotpSecret, oneTimePassword: string): TotpMultiFactorAssertion;
static assertionForSignIn(enrollmentId: string, oneTimePassword: string): TotpMultiFactorAssertion;
// Warning: (ae-forgotten-export) The symbol "FactorId" needs to be exported by the entry point index.d.ts
static FACTOR_ID: FactorId_2;
static generateSecret(session: MultiFactorSession): Promise<TotpSecret>;
}

// @public
export interface TotpMultiFactorInfo extends MultiFactorInfo {
}

// @public
export class TotpSecret {
readonly codeIntervalSeconds: number;
readonly codeLength: number;
readonly enrollmentCompletionDeadline: string;
// Warning: (ae-forgotten-export) The symbol "StartTotpMfaEnrollmentResponse" needs to be exported by the entry point index.d.ts
//
// @internal (undocumented)
static _fromStartTotpMfaEnrollmentResponse(response: StartTotpMfaEnrollmentResponse, auth: AuthInternal): TotpSecret;
generateQrCodeUrl(accountName?: string, issuer?: string): string;
readonly hashingAlgorithm: string;
// Warning: (ae-forgotten-export) The symbol "TotpVerificationInfo" needs to be exported by the entry point index.d.ts
//
// @internal (undocumented)
_makeTotpVerificationInfo(otp: string): TotpVerificationInfo;
readonly secretKey: string;
}

// @public
export class TwitterAuthProvider extends BaseOAuthProvider {
constructor();
Expand Down
5 changes: 5 additions & 0 deletions docs-devsite/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Firebase Authentication
| [PhoneMultiFactorGenerator](./auth.phonemultifactorgenerator.md#phonemultifactorgenerator_class) | Provider for generating a [PhoneMultiFactorAssertion](./auth.phonemultifactorassertion.md#phonemultifactorassertion_interface)<!-- -->. |
| [RecaptchaVerifier](./auth.recaptchaverifier.md#recaptchaverifier_class) | An [reCAPTCHA](https://www.google.com/recaptcha/)<!-- -->-based application verifier. |
| [SAMLAuthProvider](./auth.samlauthprovider.md#samlauthprovider_class) | An [AuthProvider](./auth.authprovider.md#authprovider_interface) for SAML. |
| [TotpMultiFactorGenerator](./auth.totpmultifactorgenerator.md#totpmultifactorgenerator_class) | Provider for generating a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface)<!-- -->. |
| [TotpSecret](./auth.totpsecret.md#totpsecret_class) | Provider for generating a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface)<!-- -->.<!-- -->Stores the shared secret key and other parameters to generate time-based OTPs. Implements methods to retrieve the shared secret key, generate a QRCode URL. |
| [TwitterAuthProvider](./auth.twitterauthprovider.md#twitterauthprovider_class) | Provider for generating an [OAuthCredential](./auth.oauthcredential.md#oauthcredential_class) for [ProviderId](./auth.md#providerid)<!-- -->.TWITTER. |

## Interfaces
Expand Down Expand Up @@ -130,6 +132,8 @@ Firebase Authentication
| [PopupRedirectResolver](./auth.popupredirectresolver.md#popupredirectresolver_interface) | A resolver used for handling DOM specific operations like [signInWithPopup()](./auth.md#signinwithpopup) or [signInWithRedirect()](./auth.md#signinwithredirect)<!-- -->. |
| [ReactNativeAsyncStorage](./auth.reactnativeasyncstorage.md#reactnativeasyncstorage_interface) | Interface for a supplied <code>AsyncStorage</code>. |
| [RecaptchaParameters](./auth.recaptchaparameters.md#recaptchaparameters_interface) | Interface representing reCAPTCHA parameters.<!-- -->See the \[reCAPTCHA docs\](https://developers.google.com/recaptcha/docs/display\#render\_param) for the list of accepted parameters. All parameters are accepted except for <code>sitekey</code>: Firebase Auth provisions a reCAPTCHA for each project and will configure the site key upon rendering.<!-- -->For an invisible reCAPTCHA, set the <code>size</code> key to <code>invisible</code>. |
| [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) | The class for asserting ownership of a totp second factor. Provided by [TotpMultiFactorGenerator.assertionForEnrollment()](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorassertionforenrollment) and [TotpMultiFactorGenerator.assertionForSignIn()](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorassertionforsignin)<!-- -->. |
| [TotpMultiFactorInfo](./auth.totpmultifactorinfo.md#totpmultifactorinfo_interface) | The subclass of the [MultiFactorInfo](./auth.multifactorinfo.md#multifactorinfo_interface) interface for TOTP second factors. The <code>factorId</code> of this second factor is [FactorId](./auth.md#factorid)<!-- -->.TOTP. |
| [User](./auth.user.md#user_interface) | A user account. |
| [UserCredential](./auth.usercredential.md#usercredential_interface) | A structure containing a [User](./auth.user.md#user_interface)<!-- -->, the [OperationType](./auth.md#operationtype)<!-- -->, and the provider ID. |
| [UserInfo](./auth.userinfo.md#userinfo_interface) | User profile information, visible only to the Firebase project's apps. |
Expand Down Expand Up @@ -1855,6 +1859,7 @@ An enum of factors that may be used for multifactor authentication.
```typescript
FactorId: {
readonly PHONE: "phone";
readonly TOTP: "totp";
}
```

Expand Down
21 changes: 21 additions & 0 deletions docs-devsite/auth.totpmultifactorassertion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Project: /docs/reference/js/_project.yaml
Book: /docs/reference/_book.yaml
page_type: reference

{% comment %}
DO NOT EDIT THIS FILE!
This is generated by the JS SDK team, and any local changes will be
overwritten. Changes should be made in the source code at
https://github.com/firebase/firebase-js-sdk
{% endcomment %}

# TotpMultiFactorAssertion interface
The class for asserting ownership of a totp second factor. Provided by [TotpMultiFactorGenerator.assertionForEnrollment()](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorassertionforenrollment) and [TotpMultiFactorGenerator.assertionForSignIn()](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorassertionforsignin)<!-- -->.

<b>Signature:</b>

```typescript
export interface TotpMultiFactorAssertion extends MultiFactorAssertion
```
<b>Extends:</b> [MultiFactorAssertion](./auth.multifactorassertion.md#multifactorassertion_interface)

112 changes: 112 additions & 0 deletions docs-devsite/auth.totpmultifactorgenerator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
Project: /docs/reference/js/_project.yaml
Book: /docs/reference/_book.yaml
page_type: reference

{% comment %}
DO NOT EDIT THIS FILE!
This is generated by the JS SDK team, and any local changes will be
overwritten. Changes should be made in the source code at
https://github.com/firebase/firebase-js-sdk
{% endcomment %}

# TotpMultiFactorGenerator class
Provider for generating a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface)<!-- -->.

<b>Signature:</b>

```typescript
export declare class TotpMultiFactorGenerator
```

## Properties

| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [FACTOR\_ID](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorfactor_id) | <code>static</code> | FactorId | The identifier of the TOTP second factor: <code>totp</code>. |

## Methods

| Method | Modifiers | Description |
| --- | --- | --- |
| [assertionForEnrollment(secret, oneTimePassword)](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorassertionforenrollment) | <code>static</code> | Provides a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) to confirm ownership of the totp(Time-based One Time Password) second factor. This assertion is used to complete enrollment in TOTP second factor. |
| [assertionForSignIn(enrollmentId, oneTimePassword)](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorassertionforsignin) | <code>static</code> | Provides a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) to confirm ownership of the totp second factor. This assertion is used to complete signIn with TOTP as the second factor. |
| [generateSecret(session)](./auth.totpmultifactorgenerator.md#totpmultifactorgeneratorgeneratesecret) | <code>static</code> | Returns a promise to [TotpSecret](./auth.totpsecret.md#totpsecret_class) which contains the TOTP shared secret key and other parameters. Creates a TOTP secret as part of enrolling a TOTP second factor. Used for generating a QRCode URL or inputting into a TOTP App. This method uses the auth instance corresponding to the user in the multiFactorSession. |

## TotpMultiFactorGenerator.FACTOR\_ID

The identifier of the TOTP second factor: `totp`<!-- -->.

<b>Signature:</b>

```typescript
static FACTOR_ID: FactorId;
```

## TotpMultiFactorGenerator.assertionForEnrollment()

Provides a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) to confirm ownership of the totp(Time-based One Time Password) second factor. This assertion is used to complete enrollment in TOTP second factor.

<b>Signature:</b>

```typescript
static assertionForEnrollment(secret: TotpSecret, oneTimePassword: string): TotpMultiFactorAssertion;
```

### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| secret | [TotpSecret](./auth.totpsecret.md#totpsecret_class) | A [TotpSecret](./auth.totpsecret.md#totpsecret_class) containing the shared secret key and other TOTP parameters. |
| oneTimePassword | string | One-time password from TOTP App. |

<b>Returns:</b>

[TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface)

A [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) which can be used with [MultiFactorUser.enroll()](./auth.multifactoruser.md#multifactoruserenroll)<!-- -->.

## TotpMultiFactorGenerator.assertionForSignIn()

Provides a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) to confirm ownership of the totp second factor. This assertion is used to complete signIn with TOTP as the second factor.

<b>Signature:</b>

```typescript
static assertionForSignIn(enrollmentId: string, oneTimePassword: string): TotpMultiFactorAssertion;
```

### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| enrollmentId | string | identifies the enrolled TOTP second factor. |
| oneTimePassword | string | One-time password from TOTP App. |

<b>Returns:</b>

[TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface)

A [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface) which can be used with [MultiFactorResolver.resolveSignIn()](./auth.multifactorresolver.md#multifactorresolverresolvesignin)<!-- -->.

## TotpMultiFactorGenerator.generateSecret()

Returns a promise to [TotpSecret](./auth.totpsecret.md#totpsecret_class) which contains the TOTP shared secret key and other parameters. Creates a TOTP secret as part of enrolling a TOTP second factor. Used for generating a QRCode URL or inputting into a TOTP App. This method uses the auth instance corresponding to the user in the multiFactorSession.

<b>Signature:</b>

```typescript
static generateSecret(session: MultiFactorSession): Promise<TotpSecret>;
```

### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| session | [MultiFactorSession](./auth.multifactorsession.md#multifactorsession_interface) | The [MultiFactorSession](./auth.multifactorsession.md#multifactorsession_interface) that the user is part of. |

<b>Returns:</b>

Promise&lt;[TotpSecret](./auth.totpsecret.md#totpsecret_class)<!-- -->&gt;

A promise to [TotpSecret](./auth.totpsecret.md#totpsecret_class)<!-- -->.

21 changes: 21 additions & 0 deletions docs-devsite/auth.totpmultifactorinfo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Project: /docs/reference/js/_project.yaml
Book: /docs/reference/_book.yaml
page_type: reference

{% comment %}
DO NOT EDIT THIS FILE!
This is generated by the JS SDK team, and any local changes will be
overwritten. Changes should be made in the source code at
https://github.com/firebase/firebase-js-sdk
{% endcomment %}

# TotpMultiFactorInfo interface
The subclass of the [MultiFactorInfo](./auth.multifactorinfo.md#multifactorinfo_interface) interface for TOTP second factors. The `factorId` of this second factor is [FactorId](./auth.md#factorid)<!-- -->.TOTP.

<b>Signature:</b>

```typescript
export interface TotpMultiFactorInfo extends MultiFactorInfo
```
<b>Extends:</b> [MultiFactorInfo](./auth.multifactorinfo.md#multifactorinfo_interface)

111 changes: 111 additions & 0 deletions docs-devsite/auth.totpsecret.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
Project: /docs/reference/js/_project.yaml
Book: /docs/reference/_book.yaml
page_type: reference

{% comment %}
DO NOT EDIT THIS FILE!
This is generated by the JS SDK team, and any local changes will be
overwritten. Changes should be made in the source code at
https://github.com/firebase/firebase-js-sdk
{% endcomment %}

# TotpSecret class
Provider for generating a [TotpMultiFactorAssertion](./auth.totpmultifactorassertion.md#totpmultifactorassertion_interface)<!-- -->.

Stores the shared secret key and other parameters to generate time-based OTPs. Implements methods to retrieve the shared secret key, generate a QRCode URL.

<b>Signature:</b>

```typescript
export declare class TotpSecret
```

## Properties

| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [codeIntervalSeconds](./auth.totpsecret.md#totpsecretcodeintervalseconds) | | number | The interval (in seconds) when the OTP codes should change. |
| [codeLength](./auth.totpsecret.md#totpsecretcodelength) | | number | Length of the one-time passwords to be generated. |
| [enrollmentCompletionDeadline](./auth.totpsecret.md#totpsecretenrollmentcompletiondeadline) | | string | The timestamp(UTC string) by which TOTP enrollment should be completed. |
| [hashingAlgorithm](./auth.totpsecret.md#totpsecrethashingalgorithm) | | string | Hashing algorithm used. |
| [secretKey](./auth.totpsecret.md#totpsecretsecretkey) | | string | Shared secret key/seed used for enrolling in TOTP MFA and generating OTPs. |

## Methods

| Method | Modifiers | Description |
| --- | --- | --- |
| [generateQrCodeUrl(accountName, issuer)](./auth.totpsecret.md#totpsecretgenerateqrcodeurl) | | Returns a QRCode URL as described in https://github.com/google/google-authenticator/wiki/Key-Uri-Format This can be displayed to the user as a QRCode to be scanned into a TOTP App like Google Authenticator. If the optional parameters are unspecified, an accountName of <userEmail> and issuer of <firebaseAppName> are used. |

## TotpSecret.codeIntervalSeconds

The interval (in seconds) when the OTP codes should change.

<b>Signature:</b>

```typescript
readonly codeIntervalSeconds: number;
```

## TotpSecret.codeLength

Length of the one-time passwords to be generated.

<b>Signature:</b>

```typescript
readonly codeLength: number;
```

## TotpSecret.enrollmentCompletionDeadline

The timestamp(UTC string) by which TOTP enrollment should be completed.

<b>Signature:</b>

```typescript
readonly enrollmentCompletionDeadline: string;
```

## TotpSecret.hashingAlgorithm

Hashing algorithm used.

<b>Signature:</b>

```typescript
readonly hashingAlgorithm: string;
```

## TotpSecret.secretKey

Shared secret key/seed used for enrolling in TOTP MFA and generating OTPs.

<b>Signature:</b>

```typescript
readonly secretKey: string;
```

## TotpSecret.generateQrCodeUrl()

Returns a QRCode URL as described in https://github.com/google/google-authenticator/wiki/Key-Uri-Format This can be displayed to the user as a QRCode to be scanned into a TOTP App like Google Authenticator. If the optional parameters are unspecified, an accountName of <userEmail> and issuer of <firebaseAppName> are used.

<b>Signature:</b>

```typescript
generateQrCodeUrl(accountName?: string, issuer?: string): string;
```

### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| accountName | string | the name of the account/app along with a user identifier. |
| issuer | string | issuer of the TOTP(likely the app name). |

<b>Returns:</b>

string

A QRCode URL string.

20 changes: 20 additions & 0 deletions packages/auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ host of npm scripts to run these tests. The most important commands are:
| `yarn test:<platform>:unit:debug` | Runs \<platform> unit tests, auto-watching for file system changes |
| `yarn test:<platform>:integration` | Runs only integration tests against the live environment |
| `yarn test:<platform>:integration:local` | Runs all headless \<platform> integration tests against the emulator (more below) |
| `yarn test:browser:integration:prodbackend` | Runs TOTP MFA integration tests against the backend (more below) |

Where \<platform> is "browser" or "node". There are also cordova tests, but they
are not broken into such granular details. Check out `package.json` for more.
Expand Down Expand Up @@ -46,6 +47,25 @@ you would simply execute the following command:
firebase emulators:exec --project foo-bar --only auth "yarn test:integration:local"
```

### Integration testing with the production backend

Currently, MFA TOTP tests only run against the production backend (since they are not supported on the emulator yet).
Running against the backend also makes it a more reliable end-to-end test.

The TOTP tests require the following email/password combination to exist in the project, so if you are running this test against your test project, please create this user:

'totpuser-donotdelete@test.com', 'password'

You also need to verify this email address, in order to use MFA. This can be done with a curl command like this:

```
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJECT_ID}" -X POST https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode -d '{
"email": "totpuser-donotdelete@test.com",
"requestType": "VERIFY_EMAIL",
"returnOobLink": true,
}'
```

### Selenium Webdriver tests

These tests assume that you have both Firefox and Chrome installed on your
Expand Down
Loading