Added ErrorReceived to embedded auth server

Also style the default HTML site based on error/success values. Fixes #566
This commit is contained in:
Jonas Dellinger 2021-04-15 17:54:43 +02:00
parent ddb1dc0cc0
commit 163200f65c
6 changed files with 97 additions and 50 deletions

View File

@ -81,6 +81,7 @@ public static async Task Main()
await _server.Start();
_server.AuthorizationCodeReceived += OnAuthorizationCodeReceived;
_server.ErrorReceived += OnErrorReceived;
var request = new LoginRequest(_server.BaseUri, "ClientId", LoginRequest.ResponseType.Code)
{
@ -103,6 +104,12 @@ private static async Task OnAuthorizationCodeReceived(object sender, Authorizati
var spotify = new SpotifyClient(tokenResponse.AccessToken);
// do calls with Spotify and save token?
}
private static async Task OnErrorReceived(object sender, string error, string state)
{
Console.WriteLine($"Aborting authorization, error received: {error}");
await _server.Stop();
}
```
For real examples, have a look at [Example.CLI.PersistentConfig](https://github.com/JohnnyCrazy/SpotifyAPI-NET/tree/master/SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig) and [Example.CLI.CustomHTML](https://github.com/JohnnyCrazy/SpotifyAPI-NET/tree/master/SpotifyAPI.Web.Examples/Example.CLI.CustomHTML)

View File

@ -89,6 +89,7 @@ public static async Task Main()
await _server.Start();
_server.ImplictGrantReceived += OnImplicitGrantReceived;
_server.ErrorReceived += OnErrorReceived;
var request = new LoginRequest(_server.BaseUri, "ClientId", LoginRequest.ResponseType.Token)
{
@ -103,6 +104,12 @@ private static async Task OnImplicitGrantReceived(object sender, ImplictGrantRes
var spotify = new SpotifyClient(response.AccessToken);
// do calls with Spotify
}
private static async Task OnErrorReceived(object sender, string error, string state)
{
Console.WriteLine($"Aborting authorization, error received: {error}");
await _server.Stop();
}
```
For real examples, have a look at [Example.CLI.PersistentConfig](https://github.com/JohnnyCrazy/SpotifyAPI-NET/tree/master/SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig) and [Example.CLI.CustomHTML](https://github.com/JohnnyCrazy/SpotifyAPI-NET/tree/master/SpotifyAPI.Web.Examples/Example.CLI.CustomHTML)

View File

@ -14,6 +14,7 @@ namespace SpotifyAPI.Web.Auth
{
public event Func<object, AuthorizationCodeResponse, Task>? AuthorizationCodeReceived;
public event Func<object, ImplictGrantResponse, Task>? ImplictGrantReceived;
public event Func<object, string, string?, Task>? ErrorReceived;
private const string AssetsResourcePath = "SpotifyAPI.Web.Auth.Resources.auth_assets";
private const string DefaultResourcePath = "SpotifyAPI.Web.Auth.Resources.default_site";
@ -38,6 +39,7 @@ namespace SpotifyAPI.Web.Auth
var error = query["error"];
if (error != null)
{
ErrorReceived?.Invoke(this, error, query["state"]);
throw new AuthException(error, query["state"]);
}

View File

@ -20,3 +20,7 @@ main {
.logo {
margin-bottom: 50px;
}
.hidden {
visibility: hidden;
}

View File

@ -1,43 +1,54 @@
function getUrlParams(hash, start) {
const hashes = hash.slice(hash.indexOf(start) + 1).split('&')
const hashes = hash.slice(hash.indexOf(start) + 1).split("&");
if (!hashes || hashes.length === 0 || hashes[0] === "") {
return undefined;
}
const params = {}
hashes.map(hash => {
const [key, val] = hash.split('=')
params[key] = decodeURIComponent(val)
})
return params
const params = {};
hashes.map((hash) => {
const [key, val] = hash.split("=");
params[key] = decodeURIComponent(val);
});
return params;
}
function handleImplicitGrant() {
const params = getUrlParams(window.location.hash, '#');
const params = getUrlParams(window.location.hash, "#");
if (!params) {
return;
}
params.request_type = "token";
console.log("Sent request_type token to server", params);
fetch('?' + new URLSearchParams(params).toString(), {
method: 'POST',
fetch("?" + new URLSearchParams(params).toString(), {
method: "POST",
});
}
handleImplicitGrant();
function handleAuthenticationCode() {
const params = getUrlParams(window.location.search, '?');
const params = getUrlParams(window.location.search, "?");
if (!params) {
return;
}
params.request_type = "code";
console.log("Sent request_type code to server", params);
fetch('?' + new URLSearchParams(params).toString(), {
method: 'POST',
fetch("?" + new URLSearchParams(params).toString(), {
method: "POST",
});
}
handleAuthenticationCode();
document.addEventListener("DOMContentLoaded", () => {
const errorContainer = document.querySelector("#error");
const successContainer = document.querySelector("#success");
const params = new URLSearchParams(window.location.search);
if (params.has("error")) {
errorContainer.classList.remove("hidden");
} else {
successContainer.classList.remove("hidden");
}
});

View File

@ -1,13 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Spotify Authorization</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link href="/auth_assets/main.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"
rel="stylesheet"
/>
<link href="/auth_assets/main.css" rel="stylesheet" />
<script src="/auth_assets/main.js"></script>
</head>
@ -18,21 +20,35 @@
<img src="/auth_assets/logo.svg" width="120" height="120" />
</div>
</div>
<div id="error" class="hidden">
<h1 class="text-4xl">Error!</h1>
<p class="text-xl mx-2">
Spotify Authorization was not successful. You may want to retry.
</p>
</div>
<div id="success" class="hidden">
<h1 class="text-4xl">Success!</h1>
<p class="text-xl mx-2">
Spotify Authorization was successful. You can close this tab and go back to your app.
Spotify Authorization was successful. You can close this tab and go
back to your app.
</p>
</div>
<div class="text-center py-4 lg:px-4 my-6">
<div class="p-2 bg-teal-800 items-center text-teal-100 leading-none lg:rounded-full flex lg:inline-flex"
role="alert">
<span class="flex rounded-full bg-teal-500 uppercase px-2 py-1 text-xs font-bold mr-3">Tip</span>
<div
class="p-2 bg-teal-800 items-center text-teal-100 leading-none lg:rounded-full flex lg:inline-flex"
role="alert"
>
<span
class="flex rounded-full bg-teal-500 uppercase px-2 py-1 text-xs font-bold mr-3"
>Tip</span
>
<span class="font-semibold mr-2 text-left flex-auto">
If the app does not detect the authorization, make sure you use one of the following supported Browsers:
If the app does not detect the authorization, make sure you use one
of the following supported Browsers:
<b>Chrome</b>, <b>Edge</b> or <b>Firefox</b>
</span>
</div>
</div>
</main>
</body>
</html>