diff --git a/server/AyaNova/Controllers/AuthController.cs b/server/AyaNova/Controllers/AuthController.cs index 9e616484..24b18f0d 100644 --- a/server/AyaNova/Controllers/AuthController.cs +++ b/server/AyaNova/Controllers/AuthController.cs @@ -428,13 +428,13 @@ namespace AyaNova.Api.Controllers } /// - /// Generate HOTP secret and return for use in auth app + /// Generate TOTP secret and return for use in auth app /// /// /// From route path - /// New HOTP secret - [HttpGet("hotp")] - public async Task GenerateAndSendHOTP(ApiVersion apiVersion) + /// New TOTP secret + [HttpGet("totp")] + public async Task GenerateAndSendTOTP(ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); @@ -451,18 +451,33 @@ namespace AyaNova.Api.Controllers return StatusCode(403, new ApiNotAuthorizedResponse()); var tfa = new TwoFactorAuth("AyaNova"); - u.HotpSecret = tfa.CreateSecret(160); + u.TotpSecret = tfa.CreateSecret(160); await ct.SaveChangesAsync(); +//https://github.com/google/google-authenticator/wiki/Key-Uri-Format + + QRCoder.PayloadGenerator.OneTimePassword generator = new QRCoder.PayloadGenerator.OneTimePassword() + { + Secret = u.TotpSecret, + Issuer = "AyaNova", + //Label = $"AyaNova.{u.Id}", + Type = QRCoder.PayloadGenerator.OneTimePassword.OneTimePasswordAuthType.TOTP + }; + string payload = generator.ToString(); + + // QRCodeGenerator qrGenerator = new QRCodeGenerator(); + // QRCodeData qrCodeData = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q); + // QRCode qrCode = new QRCode(qrCodeData); + // var qrCodeAsBitmap = qrCode.GetGraphic(20); QRCodeGenerator qrGenerator = new QRCodeGenerator(); - QRCodeData qrCodeData = qrGenerator.CreateQrCode(u.HotpSecret, QRCodeGenerator.ECCLevel.Q); + QRCodeData qrCodeData = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q); Base64QRCode qrCode = new Base64QRCode(qrCodeData); - string qrCodeImageAsBase64 = qrCode.GetGraphic(20); + string qrCodeImageAsBase64 = qrCode.GetGraphic(4); return Ok(ApiOkResponse.Response(new { - s = u.HotpSecret, + s = u.TotpSecret, qr = qrCodeImageAsBase64 })); } diff --git a/server/AyaNova/models/User.cs b/server/AyaNova/models/User.cs index c281afd7..0f63be1f 100644 --- a/server/AyaNova/models/User.cs +++ b/server/AyaNova/models/User.cs @@ -97,7 +97,7 @@ namespace AyaNova.Models [JsonIgnore] public DateTime? PasswordResetCodeExpire { get; set; }//--- [JsonIgnore] - public string HotpSecret { get; set; }//--- + public string TotpSecret { get; set; }//--- //========================== //relations diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index c5f535df..63a37401 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -441,7 +441,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); //Add user table await ExecQueryAsync("CREATE TABLE auser (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, active BOOL NOT NULL, name TEXT NOT NULL UNIQUE, " + "lastlogin TIMESTAMP, login TEXT NOT NULL UNIQUE, password TEXT NOT NULL, salt TEXT NOT NULL, roles INTEGER NOT NULL, currentauthtoken TEXT, " - + "dlkey TEXT, dlkeyexpire TIMESTAMP, hotpsecret TEXT, twofactorenabled BOOL, passwordresetcode TEXT, passwordresetcodeexpire TIMESTAMP, usertype INTEGER NOT NULL, " + + "dlkey TEXT, dlkeyexpire TIMESTAMP, totpsecret TEXT, twofactorenabled BOOL, passwordresetcode TEXT, passwordresetcodeexpire TIMESTAMP, usertype INTEGER NOT NULL, " + "employeenumber TEXT, notes TEXT, customerid BIGINT, " + "headofficeid BIGINT, vendorid BIGINT, wiki TEXT, customfields TEXT, tags VARCHAR(255) ARRAY)");