From 4328052310f0bb07df46624caa8450336a9d2a4d Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Wed, 29 Nov 2017 10:03:00 -0500 Subject: [PATCH 1/3] Update RAML spec to clarify code returned for wrong TOTP code. --- api.raml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api.raml b/api.raml index d65afd6..5015558 100644 --- a/api.raml +++ b/api.raml @@ -163,8 +163,10 @@ protocols: [HTTPS] 204: 400: description: | - The request body was invlalid, such as if no `code` value was found. + The request body was invalid, such as if no `code` value was found. 401: + description: | + The given TOTP code was wrong. 404: /u2f: From 255021c32f0393de295a1ccafee04b0970aec73f Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Fri, 1 Dec 2017 09:15:52 -0500 Subject: [PATCH 2/3] Correct RAML api spec: valid TOTP returns 200, not 204. --- api.raml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api.raml b/api.raml index 5015558..b6c6969 100644 --- a/api.raml +++ b/api.raml @@ -160,7 +160,9 @@ protocols: [HTTPS] example: | {"code": "012345"} responses: - 204: + 200: + description: | + The given TOTP code was valid. 400: description: | The request body was invalid, such as if no `code` value was found. From 66e0942d122647fb52db6fff23c61de2be47faea Mon Sep 17 00:00:00 2001 From: Matt Henderson Date: Fri, 1 Dec 2017 11:06:41 -0500 Subject: [PATCH 3/3] Properly encode `label` part of otpauth URL. --- models/totp.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/models/totp.js b/models/totp.js index f94f420..0769603 100644 --- a/models/totp.js +++ b/models/totp.js @@ -20,13 +20,17 @@ module.exports.create = (apiKeyValue, apiSecret, {issuer, label = 'SecretKey'} = const otpSecrets = speakeasy.generateSecret({length: 10}); let otpAuthUrlOptions = { - 'label': label, + 'label': encodeURIComponent(label), 'secret': otpSecrets.base32, 'encoding': 'base32' }; if (issuer) { otpAuthUrlOptions.issuer = issuer; - otpAuthUrlOptions.label = issuer + ':' + label; + + // Note: The issuer and account-name used in the `label` need to be + // URL-encoded. Presumably speakeasy doesn't automatically do so because + // the colon (:) separating them needs to NOT be encoded. + otpAuthUrlOptions.label = encodeURIComponent(issuer) + ':' + encodeURIComponent(label); } const otpAuthUrl = speakeasy.otpauthURL(otpAuthUrlOptions);