add module for api client

Add js apiclient init module
This commit is contained in:
Matthew Strasiotto
2022-08-14 13:13:06 +10:00
committed by Matthew Strasitoto
parent cc05b12a23
commit f810ea7259
5 changed files with 160 additions and 3 deletions
+2 -2
View File
@@ -112,9 +112,9 @@ public class SSOViewsController : ControllerBase
}
/// <summary>
/// Returns the shared js module that initializes the ApiClient.
/// Get the shared js module that initializes the ApiClient.
/// </summary>
/// <returns>The html view for the linking interface.</returns>
/// <returns>Returns the shared js module that initializes the ApiClient.</returns>
// [Authorize(Policy = "DefaultAuthorization")]
[HttpGet("ApiClient.js")]
public ActionResult GetApiClientView()
+9 -1
View File
@@ -1,7 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>SSO</title>
<script>
import("./ApiClient.js").then((apiclient) => {
import("./linking.js").then((renderer) => {
const view = document.querySelector("#sso-config-page");
renderer.default(view);
});
});
</script>
<title>SSO Linking</title>
</head>
<body>
<div
+2
View File
@@ -14,11 +14,13 @@
<None Remove="Config\config.js" />
<None Remove="Config\style.css" />
<None Remove="Config\linking.html" />
<None Remove="Views\apiClient.js" />
<EmbeddedResource Include="Config\configPage.html" />
<EmbeddedResource Include="Config\config.js" />
<EmbeddedResource Include="Config\style.css" />
<EmbeddedResource Include="Config\linking.html" />
<EmbeddedResource Include="Config\linking.js" />
<EmbeddedResource Include="Views\apiClient.js" />
</ItemGroup>
<ItemGroup>
+5
View File
@@ -98,6 +98,11 @@ public class SSOPlugin : BasePlugin<PluginConfiguration>, IPlugin, IHasWebPages
Name = Name + "-linking.js",
EmbeddedResourcePath = $"{GetType().Namespace}.Config.linking.js"
},
new PluginPageInfo
{
Name = Name + "-ApiClient.js",
EmbeddedResourcePath = $"{GetType().Namespace}.Views.apiClient.js"
},
};
}
}
+142
View File
@@ -0,0 +1,142 @@
import jellyfinApiclient from "https://esm.run/jellyfin-apiclient";
window.jellyfinApiclient = jellyfinApiclient;
console.log(jellyfinApiclient);
// https://github.com/jellyfin/jellyfin-web/blob/9067b0e397cc8b38635d661ce86ddd83194f3202/src/scripts/clientUtils.js#L19-L76
export async function serverAddress() {
const apiClient = window.ApiClient;
if (apiClient) {
return Promise.resolve(apiClient.serverAddress());
}
const urls = [];
if (urls.length === 0) {
// Otherwise use computed base URL
let url;
const index = window.location.href.toLowerCase().lastIndexOf("/web");
if (index != -1) {
url = window.location.href.substring(0, index);
} else {
// fallback to location without path
url = window.location.origin;
}
// Don't use bundled app URL (file:) as server URL
if (url.startsWith("file:")) {
return Promise.resolve();
}
urls.push(url);
}
console.debug("URL candidates:", urls);
const promises = urls.map((url) => {
return fetch(`${url}/System/Info/Public`)
.then((resp) => {
return {
url: url,
response: resp,
};
})
.catch(() => {
return Promise.resolve();
});
});
return Promise.all(promises)
.then((responses) => {
responses = responses.filter((obj) => obj && obj.response.ok);
return Promise.all(
responses.map((obj) => {
return {
url: obj.url,
config: obj.response.json(),
};
})
);
})
.then((configs) => {
const selection =
configs.find((obj) => !obj.config.StartupWizardCompleted) || configs[0];
return Promise.resolve(selection?.url);
})
.catch((error) => {
console.log(error);
return Promise.resolve();
});
}
// TODO: Refactor duplicated code
// ! Duplicated at
// https://github.com/9p4/jellyfin-plugin-sso/blob/38558d762a13422862240af4060bdd1bb1618d57/SSO-Auth/WebResponse.cs#L363-L401
function getDeviceName() {
return "DUMMY";
}
function getDeviceId() {
return localStorage.getItem("_deviceId2");
}
const sleep = (milliseconds) => {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
};
async function awaitLocalStorage() {
while (
localStorage.getItem("_deviceId2") == null ||
localStorage.getItem("jellyfin_credentials") == null ||
JSON.parse(localStorage.getItem("jellyfin_credentials"))["Servers"][0][
"Id"
] == null
) {
// If localStorage isn't initialized yet, try again.
await sleep(100);
}
}
await awaitLocalStorage();
// Fetch credentials
var credentials = new jellyfinApiclient.Credentials();
var server = await serverAddress();
console.log({ server: server });
var deviceId = getDeviceId();
var appName = "SSO-Auth";
var appVersion = "0.0.0.9000";
var capabilities = {};
const current_server = credentials
.credentials()
.Servers.find((e) => e.LocalAddress == server || e.ManualAddress == server);
var localApiClient = new jellyfinApiclient.ApiClient(
server,
appName,
appVersion,
getDeviceName(),
deviceId
);
localApiClient.setAuthenticationInfo(
current_server.AccessToken,
current_server.UserId
);
var connections = new jellyfinApiclient.ConnectionManager(
credentials,
appName,
appVersion,
getDeviceName(),
deviceId,
capabilities
);
connections.addApiClient(localApiClient);
window.ApiClient = localApiClient;
export default localApiClient;