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

#14423 User can verify multiple times with the same two factor token #57728

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions src/Identity/Extensions.Core/src/AuthenticatorTokenProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ public virtual async Task<bool> ValidateAsync(string purpose, string token, User
#endif

var timestep = Convert.ToInt64(unixTimestamp / 30);

var storedOtpTimestamp = await manager.GetAuthenticatorTimestampAsync(user).ConfigureAwait(false);

// Do not allow re-use of TOTP codes (Section 5.2 of RFC 6238).
if (storedOtpTimestamp.HasValue && storedOtpTimestamp >= timestep)
{
return false;
}

await manager.SetAuthenticatorTimestampAsync(user, timestep).ConfigureAwait(false);

// Allow codes from 90s in each direction (we could make this configurable?)
for (int i = -2; i <= 2; i++)
{
Expand Down
21 changes: 20 additions & 1 deletion src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,27 @@
/// <summary>
/// Get the authenticator key for the specified <paramref name="user" />.
/// </summary>
/// <param name="user">The user whose security stamp should be set.</param>
/// <param name="user">The user whose security stamp should be retrieved.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the security stamp for the specified <paramref name="user"/>.</returns>
Task<string?> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken);

/// <summary>
/// Get the last verified authenticator timestamp for the specified <paramref name="user" />.
/// </summary>
/// <param name="user">The user whose authenticator timestamp should be retrieved.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>
/// The <see cref="Task"/> that represents the asynchronous operation, containing the last verified authenticator timestamp for the specified <paramref name="user"/>,
/// or null, when the authenticator code has never been verified.</returns>
Task<long?> GetAuthenticatorTimestampAsync(TUser user, CancellationToken cancellationToken);

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS arm64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS arm64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 40 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L40

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(40,17): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

/// <summary>
/// Set the last verified authenticator timestamp for the specified <paramref name="user" />.
/// </summary>
/// <param name="user">The user whose authenticator timestamp should be set.</param>
/// <param name="timestamp">The new timestamp value to be set.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the security stamp for the specified <paramref name="user"/>.</returns>
Task SetAuthenticatorTimestampAsync(TUser user, long timestamp, CancellationToken cancellationToken);

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS arm64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 49 in src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs#L49

src/Identity/Extensions.Core/src/IUserAuthenticatorKeyStore.cs(49,10): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
}
28 changes: 28 additions & 0 deletions src/Identity/Extensions.Core/src/UserManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1983,6 +1983,34 @@
return await UpdateAsync(user).ConfigureAwait(false);
}

/// <summary>
/// Returns the authenticator last verified timestamp for the user.
/// </summary>
/// <param name="user">The user.</param>
/// <returns>The authenticator key</returns>
public virtual Task<long?> GetAuthenticatorTimestampAsync(TUser user)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS arm64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS x64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux x64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl x64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 1991 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Identity/Extensions.Core/src/UserManager.cs#L1991

src/Identity/Extensions.Core/src/UserManager.cs(1991,32): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'GetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
{
ThrowIfDisposed();
var store = GetAuthenticatorKeyStore();
ArgumentNullThrowHelper.ThrowIfNull(user);
return store.GetAuthenticatorTimestampAsync(user, CancellationToken);
}

/// <summary>
/// Updates the authenticator last verified timestamp for the user.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="timestamp">The timestamp to save.</param>
/// <returns>Whether the user was successfully updated.</returns>
public virtual async Task<IdentityResult> SetAuthenticatorTimestampAsync(TUser user, long timestamp)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS arm64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: macOS x64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl ARM64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux x64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux Musl x64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Build: Linux ARM)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)

Check failure on line 2005 in src/Identity/Extensions.Core/src/UserManager.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Identity/Extensions.Core/src/UserManager.cs#L2005

src/Identity/Extensions.Core/src/UserManager.cs(2005,47): error RS0016: (NETCORE_ENGINEERING_TELEMETRY=Build) Symbol 'SetAuthenticatorTimestampAsync' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
{
ThrowIfDisposed();
var store = GetAuthenticatorKeyStore();
ArgumentNullThrowHelper.ThrowIfNull(user);
await store.SetAuthenticatorTimestampAsync(user, timestamp, CancellationToken).ConfigureAwait(false);
return await UpdateAsync(user).ConfigureAwait(false);
}

/// <summary>
/// Generates a new base32 encoded 160-bit security secret (size of SHA1 hash).
/// </summary>
Expand Down
57 changes: 55 additions & 2 deletions src/Identity/Extensions.Stores/src/UserStoreBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ public virtual async Task RemoveTokenAsync(TUser user, string loginProvider, str
private const string InternalLoginProvider = "[AspNetUserStore]";
private const string AuthenticatorKeyTokenName = "AuthenticatorKey";
private const string RecoveryCodeTokenName = "RecoveryCodes";
private const char AuthenticatorKeyTimestampSeparator = ';';

/// <summary>
/// Sets the authenticator key for the specified <paramref name="user"/>.
Expand All @@ -902,8 +903,60 @@ public virtual Task SetAuthenticatorKeyAsync(TUser user, string key, Cancellatio
/// <param name="user">The user whose security stamp should be set.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the security stamp for the specified <paramref name="user"/>.</returns>
public virtual Task<string?> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken)
=> GetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, cancellationToken);
public virtual async Task<string?> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken)
{
var token = await GetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, cancellationToken).ConfigureAwait(false);
return token?.Split(AuthenticatorKeyTimestampSeparator).First();
}

/// <summary>
/// Get the last verified authenticator timestamp for the specified <paramref name="user" />.
/// </summary>
/// <param name="user">The user whose authenticator timestamp should be retrieved.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>
/// The <see cref="Task"/> that represents the asynchronous operation, containing the last verified authenticator timestamp for the specified <paramref name="user"/>,
/// or null, when the authenticator code has never been verified.</returns>
public async Task<long?> GetAuthenticatorTimestampAsync(TUser user, CancellationToken cancellationToken)
{
var token = await GetTokenAsync(user, InternalLoginProvider, AuthenticatorKeyTokenName, cancellationToken).ConfigureAwait(false);
var keyParts = token?.Split(AuthenticatorKeyTimestampSeparator);

if (keyParts?.Length == 2)
{
if (long.TryParse(keyParts[1], out var timestamp))
{
return timestamp;
}

throw new InvalidOperationException("Invalid authenticator key and timestamp pair format");
}

return null;
}

/// <summary>
/// Set the last verified authenticator timestamp for the specified <paramref name="user" />.
/// </summary>
/// <param name="user">The user whose authenticator timestamp should be set.</param>
/// <param name="timestamp">The new timestamp value to be set.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the security stamp for the specified <paramref name="user"/>.</returns>
public async Task SetAuthenticatorTimestampAsync(TUser user, long timestamp, CancellationToken cancellationToken)
{
var key = await GetAuthenticatorKeyAsync(user, cancellationToken).ConfigureAwait(false);

if (key != null)
{
var keyTimestampPair = $"{key}{AuthenticatorKeyTimestampSeparator}{timestamp}";
await base.SetAuthenticatorKeyAsync(user, keyTimestampPair, cancellationToken);
}
else
{
throw new InvalidOperationException("Unable to store authenticator timestamp - no authenticator key exists");
}
}

/// <summary>
/// Returns how many recovery code are still valid for a user.
Expand Down
37 changes: 36 additions & 1 deletion src/Identity/test/InMemory.Test/InMemoryUserStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ public Task<string> GetTokenAsync(TUser user, string loginProvider, string name,
private const string AuthenticatorStoreLoginProvider = "[AspNetAuthenticatorStore]";
private const string AuthenticatorKeyTokenName = "AuthenticatorKey";
private const string RecoveryCodeTokenName = "RecoveryCodes";
private const char AuthenticatorKeyTimestampSeparator = ';';

public Task SetAuthenticatorKeyAsync(TUser user, string key, CancellationToken cancellationToken)
{
Expand All @@ -401,7 +402,41 @@ public Task SetAuthenticatorKeyAsync(TUser user, string key, CancellationToken c

public Task<string> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken)
{
return GetTokenAsync(user, AuthenticatorStoreLoginProvider, AuthenticatorKeyTokenName, cancellationToken);
var token = await GetTokenAsync(user, AuthenticatorStoreLoginProvider, AuthenticatorKeyTokenName, cancellationToken).ConfigureAwait(false);
return token?.Split(AuthenticatorKeyTimestampSeparator).First();
}

public async Task<long?> GetAuthenticatorTimestampAsync(TUser user, CancellationToken cancellationToken)
{
var token = await GetTokenAsync(user, AuthenticatorStoreLoginProvider, AuthenticatorKeyTokenName, cancellationToken).ConfigureAwait(false);
var keyParts = token?.Split(AuthenticatorKeyTimestampSeparator);

if (keyParts?.Length == 2)
{
if (long.TryParse(keyParts[1], out var timestamp))
{
return timestamp;
}

throw new InvalidOperationException("Invalid authenticator key and timestamp pair format");
}

return null;
}

public async Task SetAuthenticatorTimestampAsync(TUser user, long timestamp, CancellationToken cancellationToken)
{
var key = await GetAuthenticatorKeyAsync(user, cancellationToken).ConfigureAwait(false);

if (key != null)
{
var keyTimestampPair = $"{key}{AuthenticatorKeyTimestampSeparator}{timestamp}";
await base.SetAuthenticatorKeyAsync(user, keyTimestampPair, cancellationToken);
}
else
{
throw new InvalidOperationException("Unable to store authenticator timestamp - no authenticator key exists");
}
}

public Task ReplaceCodesAsync(TUser user, IEnumerable<string> recoveryCodes, CancellationToken cancellationToken)
Expand Down
Loading