Skip to content

Commit 5739bda

Browse files
committed
Improve usability of totp generate secret mutation
1 parent af5cdff commit 5739bda

5 files changed

Lines changed: 33 additions & 8 deletions

File tree

app/graphql/mutations/users/mfa/totp/generate_secret.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@ module Totp
77
class GenerateSecret < BaseMutation
88
description 'Generates an encrypted totp secret'
99

10-
field :secret, String, null: true, description: 'The created and signed secret'
10+
field :secret, String, null: true, description: 'The created secret'
11+
field :signed_secret, String, null: true, description: 'The created and signed secret'
1112

1213
def resolve
13-
::Users::Mfa::Totp::GenerateSecretService.new(current_authentication).execute
14-
.to_mutation_response(success_key: :secret)
14+
response = ::Users::Mfa::Totp::GenerateSecretService.new(current_authentication).execute
15+
16+
return response.to_mutation_response unless response.success?
17+
18+
{
19+
secret: response.payload[:secret],
20+
signed_secret: response.payload[:signed_secret],
21+
errors: [],
22+
}
1523
end
1624
end
1725
end

app/services/users/mfa/totp/generate_secret_service.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ def execute
2222
totp_secret = ROTP::Base32.random
2323

2424
ServiceResponse.success(message: 'TOTP secret generated',
25-
payload: Rails.application.message_verifier(:totp_secret)
26-
.generate(totp_secret))
25+
payload: {
26+
signed_secret: Rails.application
27+
.message_verifier(:totp_secret)
28+
.generate(totp_secret),
29+
secret: totp_secret,
30+
})
2731
end
2832
end
2933
end

docs/graphql/mutation/usersmfatotpgeneratesecret.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ Generates an encrypted totp secret
1616
|------|------|-------------|
1717
| `clientMutationId` | [`String`](../scalar/string.md) | A unique identifier for the client performing the mutation. |
1818
| `errors` | [`[Error!]!`](../object/error.md) | Errors encountered during execution of the mutation. |
19-
| `secret` | [`String`](../scalar/string.md) | The created and signed secret |
19+
| `secret` | [`String`](../scalar/string.md) | The created secret |
20+
| `signedSecret` | [`String`](../scalar/string.md) | The created and signed secret |

spec/requests/graphql/mutation/users/mfa/totp/generate_secret_mutation_spec.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
usersMfaTotpGenerateSecret(input: {}) {
1414
#{error_query}
1515
secret
16+
signedSecret
1617
}
1718
}
1819
QUERY
@@ -25,7 +26,13 @@
2526

2627
it 'generates secret' do
2728
mutate!
28-
expect(graphql_data_at(:users_mfa_totp_generate_secret, :secret)).to be_present
29+
secret = graphql_data_at(:users_mfa_totp_generate_secret, :secret)
30+
signed_secret = graphql_data_at(:users_mfa_totp_generate_secret, :signed_secret)
31+
32+
expect(secret).to be_present
33+
34+
signed_totp = Rails.application.message_verifier(:totp_secret).verify(signed_secret)
35+
expect(signed_totp).to eq(secret)
2936
end
3037
end
3138
end

spec/services/users/mfa/totp/generate_secret_service_spec.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@
2626
it { is_expected.to be_success }
2727

2828
it 'is valid totp secret' do
29-
totp = ROTP::TOTP.new(service_response.payload.split('--').first)
29+
totp = ROTP::TOTP.new(service_response.payload[:signed_secret].split('--').first)
3030
expect(totp.secret.length).to eq(48)
3131
end
32+
33+
it 'returns a matching secret' do
34+
signed_totp = Rails.application.message_verifier(:totp_secret).verify(service_response.payload[:signed_secret])
35+
expect(signed_totp).to eq(service_response.payload[:secret])
36+
end
3237
end
3338
end
3439
end

0 commit comments

Comments
 (0)