public async Task InvokeAsync(HttpContext ctx) { var options = ctx.RequestServices.GetService <SQRLOptions>() ?? new SQRLOptions(); if (ctx.Request.Path != options.LoginPath || ctx.Request.Method != HttpMethods.Post || !ctx.Request.IsHttps) { await _next(ctx); return; } //todo: validate nut var cache = ctx.RequestServices.GetService <IMemoryCache>(); var userRepo = ctx.RequestServices.GetService <IUserRepo>(); var auth = new SQRLVM { Client = ctx.Request.Form["client"], Ids = ctx.Request.Form["ids"], Server = ctx.Request.Form["server"] }; var req = SQRL.DecodeRequest(ctx.Request.Host.Value, RequestIP(), auth); var res = SQRL.ComoseResponse(req, userRepo.Get, userRepo.Update, (key, user) => { cache.Set(key, user); }); if (req.cmd != "query") { res.url = options.CPSPath(ctx, res.nut); } var rv = res.Serialize(); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/x-www-form-urlencoded"; ctx.Response.ContentLength = rv.Length; await ctx.Response.WriteAsync(rv); string RequestIP() => ctx.Request.IsHttps ? ctx.Request.Host.Host == "localhost" ? "127.0.0.1" : ctx.Request.Host.Host : "0.0.0.0"; }
public static SQRLRequest DecodeRequest(string host, string ipAddress, SQRLVM vm) { var dict = Unpack(FromBase64URL(vm.Client).UTF8String()); var rv = new SQRLRequest { idk = dict.GetOrDefault("idk"), suk = dict.GetOrDefault("suk"), vuk = dict.GetOrDefault("vuk"), cmd = dict.GetOrDefault("cmd"), Signature = FromBase64URL(vm.Ids), }; rv.PublicKey = FromBase64URL(rv.idk); rv.IsValid = ValidateSQRLPost(rv.Signature, vm.Client, vm.Server, rv.PublicKey); rv.RequestIP = ipAddress; rv.Host = host; return(rv); }