代码拉取完成,页面将自动刷新
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Auth for Mastodon</title>
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.4/css/bulma.min.css" /> -->
<link rel="stylesheet" href="/css/auth.css" />
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
<h1 class="title is-1"><a href="/">Auth for Mastodon</a></h1>
</div>
</div>
</section>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-5">
<form method="post" action="#" id="sbmt">
<article class="message is-info">
<div class="message-header">
<p>Info</p>
</div>
<div class="message-body">
<div>All login information will be saved in your browser, and this website will not store and transmit your login information.</div>
<div>Client Name: <a id="client_name">Client Name</a></div>
<div>Website: <a id="website">Website</a></div>
</div>
</article>
<div class="field">
<label class="label" for="mastodon_url">Mastodon URL ( https://mastodon.social ,
https://mstdn.jp , https://mstdn.social ...)</label>
<p class="control has-icon has-icons-left">
<input class="input is-primary" type="text" id="mastodon_url" required>
</p>
</div>
<div class="field">
<label class="label">Scopes</label>
<p class="control">
<span class="select">
<select name="scopes" id="scopes">
<option>read:search write:statuses</option>
<option>read:statuses</option>
<option>read</option>
<option>write</option>
<option>follow</option>
<option>read write</option>
<option>read follow</option>
<option>write follow</option>
<option>read write follow</option>
</select>
</span>
</p>
</div>
<div class="field">
<p class="control">
<button class="button is-primary" type="submit" id="btn" name="btn">Auth</button>
<button class="button is-danger" type="button" id="btn_clr" name="btn_clr">Clear
Cache</button>
<button class="button is-primary" type="button" id="btn_back"
name="btn_back">Back</button>
</p>
</div>
</form>
</div>
<div class="column">
<article class="message is-info">
<div class="message-header">
<p>Result</p>
</div>
<div class="message-body">
<div>Client Id: </div>
<div id="client_id"></div>
<div>Client Secret:</div>
<div id="client_secret"></div>
<div>Access Token:</div>
<div id="access_token"></div>
<div>Account URL: <a id="account_url"></a></div>
</div>
</article>
<article id="info_container" class="message" style="display: none;">
<div class="message-header">
<p>Info</p>
</div>
<div class="message-body" id="info"></div>
</article>
</div>
</div>
</div>
</section>
<div class="box" style="visibility: hidden;">
Source code <a
href="https://github.com/takahashim/mastodon-access-token">https://github.com/takahashim/mastodon-access-token</a>
</div>
<script>
function elem(el) {
return document.getElementById(el);
}
function doingSomething(text) {
if (text == "") {
elem("info_container").style.display = "none";
} else {
elem("info_container").style.display = "block";
elem("info").textContent = text;
}
}
function errHandler(err) {
elem("info_container").style.display = "block";
elem("info_container").classList.add("is-danger");
elem("info").textContent = err.message;
throw new Error('Error posting data: ' + err.message);
}
function makePostData(args) {
const data = new URLSearchParams();
Object.keys(args).forEach(key => {
data.append(key, args[key]);
});
return data.toString();
}
async function post(url, args) {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: makePostData(args),
});
if (response.ok) {
const data = await response.json();
return data;
} else {
throw new Error('Network response was not ok.');
}
} catch (error) {
errHandler(error)
}
}
async function getAccountInfo(mastodon_url, mastodom_access_token) {
try {
const response = await fetch(`${mastodon_url}/api/v1/accounts/verify_credentials`, {
method: 'GET',
headers: { 'Authorization': `Bearer ${mastodom_access_token}` }
});
if (!response.ok) {
throw new Error(`Error fetching current user information: ${response.statusText}`);
}
const data = await response.json();
return data;
} catch (error) {
errHandler(error)
return null;
}
}
/* main */
const redirect_uri = window.location.origin + "/auth.html";
const app_client_name = "ftls.xyz";
const app_client_website = "https://ftls.xyz";
const mastodon_url = localStorage.getItem("MASTODON_URL");
const client_id = localStorage.getItem("MASTODON_CLIENT_ID");
const client_secret = localStorage.getItem("MASTODON_CLIENT_SECRET");
const mastodom_access_token = localStorage.getItem("MASTODON_ACCESS_TOKEN");
elem("client_name").textContent = app_client_name;
elem("website").textContent = app_client_website;
elem("client_id").textContent = client_id;
elem("client_secret").textContent = client_secret;
elem("access_token").textContent = mastodom_access_token;
elem("mastodon_url").value = mastodon_url;
elem("account_url").textContent = localStorage.getItem("MASTODON_ACCOUNT_URL")
if (mastodon_url == null) {
elem("mastodon_url").value = "https://mastodon.social";
}
if (window.location.href.includes("?code=") && mastodon_url && client_id && client_secret) {
const code = window.location.href.replace(window.location.origin + window.location.pathname + "?code=", "");
const url2 = `${mastodon_url}/oauth/token`;
elem("mastodon_url").value = mastodon_url;
elem("client_id").textContent = client_id;
elem("client_secret").textContent = client_secret;
const args2 = {
client_id: client_id,
client_secret: client_secret,
redirect_uri: redirect_uri,
grant_type: "authorization_code",
code: code,
};
post(url2, args2).then(data => {
elem('access_token').textContent = data.access_token;
localStorage.setItem("MASTODON_ACCESS_TOKEN", data.access_token);
getAccountInfo(mastodon_url, data.access_token).then(res => {
console.log(res.url);
localStorage.setItem("MASTODON_ACCOUNT_URL", res.url);
elem('account_url').textContent = res.url;
})
doingSomething("Success!");
});
}
elem("sbmt").addEventListener("submit", function (event) {
event.preventDefault();
const url = `${elem("mastodon_url").value}/api/v1/apps`;
const s = elem("scopes");
const scopes = s.options[s.selectedIndex].value;
const args = {
client_name: app_client_name,
redirect_uris: redirect_uri,
website: app_client_website,
scopes: scopes,
};
try {
doingSomething("Please wait..");
post(url, args).then(data => {
localStorage.setItem("MASTODON_URL", elem("mastodon_url").value);
localStorage.setItem("MASTODON_CLIENT_ID", data.client_id);
localStorage.setItem("MASTODON_CLIENT_SECRET", data.client_secret);
const redirectLink = `${elem("mastodon_url").value}/oauth/authorize?client_id=${data.client_id}&redirect_uri=${redirect_uri}&response_type=code&scope=${scopes}`;
window.location.href = redirectLink;
doingSomething("");
});
} catch (error) {
errHandler(error)
}
});
elem("btn_clr").addEventListener("click", function () {
elem('access_token').textContent = "";
elem('client_id').textContent = "";
elem('client_secret').textContent = "";
elem("mastodon_url").value = "https://mastodon.social";
elem("account_url").textContent = "";
localStorage.removeItem("MASTODON_URL");
localStorage.removeItem("MASTODON_CLIENT_ID");
localStorage.removeItem("MASTODON_CLIENT_SECRET");
localStorage.removeItem("MASTODON_ACCESS_TOKEN");
localStorage.removeItem("MASTODON_ACCOUNT_URL");
doingSomething("Clear Cache !");
});
elem("btn_back").addEventListener("click", function () {
window.location.href = document.referrer;
});
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。