rss-to-activitypub/public/convert/index.html
Darius Kazemi 34b46ed9fc Require OAuth 2.0 verification to create feeds
As of the `v2.0.0` release of this project, only users who are authenticated with a particular OAuth server can _create_ feeds. Any federated user can still read the feeds. I implemented this because running this service in the open invited thousands of spammers to create feeds and overwhelm the service. With this new model, you can run this as an added bonus for people in a community like a Mastodon server, and as the person running it you are taking on only the moderation burden of the users you are already responsible for on your federated server.
2021-10-12 09:12:03 -07:00

137 lines
4.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Convert an RSS feed to ActivityPub</title>
<style>
body {
font-family: sans-serif;
max-width: 800px;
margin: 30px;
}
img {
max-width: 100px;
}
li {
margin-bottom: 0.2em;
}
.account {
}
input {
width: 300px;
font-size: 1.2em;
}
.hint {
font-size: 0.8em;
}
button {
font-size: 1.2em;
}
</style>
</head>
<body>
<h1>Convert an RSS feed to ActivityPub</h1>
<p><em>by <a href="https://friend.camp/@darius">Darius Kazemi</a>, <a href="https://github.com/dariusk/rss-to-activitypub">source code here</a></em></p>
<div id="convert">
<p id="login-confirmed"></p>
<p>Put the full RSS feed URL in here, and pick a username for the account that will track the feed.</p>
<p>
<input id="feed" type="text" placeholder="https://example.com/feed.xml"/>
</p>
<p>
<input id="username" type="text" placeholder="username"/><br><span class="hint">only letters, digits, and underscore (_) allowed</span>
</p>
<p>Reminder: you won't see any posts on the account until the RSS feed updates at least once!</p>
<button onclick="submit()">Submit</button>
<div id="out">
</div>
</div>
<div id="login" hidden=true>
<p>You aren't logged in! <a href="/">Go here to log in.</a></p>
</div>
<script>
function submit() {
let domain = document.domain;
let feed = encodeURIComponent(document.querySelector('#feed').value);
let username = document.querySelector('#username').value;
let out = document.querySelector('#out');
fetch(`/api/convert/?feed=${feed}&username=${username}&token=${access_token}`)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
if (myJson.err) {
out.innerHTML = `<p>Error: ${myJson.err}</p>`;
return {};
}
// a feed exists in the database
if (myJson.content) {
// was it a match on feed
if (myJson.feed === decodeURIComponent(feed)) {
out.innerHTML = `<p>This feed already exists! Follow @${myJson.username}@${domain}.</p>`;
window.location = `/u/${myJson.username}`;
}
// was it a match on username
else if (myJson.username === username) {
out.innerHTML = `<p>This username is already taken for <a href="${myJson.feed}">this feed</a>.</p>`;
}
}
else if (myJson.title) {
out.innerHTML = `<p>Okay! There is now an ActivityPub actor for ${myJson.title}. You should be able to search for it from your ActivityPub client (Mastodon, Pleroma, etc) using this identifier: @${username}@${domain}. You won't see anything there until the next time the RSS feed updates. You can check out the profile page for this feed at <a href="https://${domain}/u/${username}/">https://${domain}/u/${username}</a> too!</p>`;
}
})
.catch(error => {
out.innerHTML = `<p>Error: ${error}</p>`;
});
}
function getUrlParameter(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(location.search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};
if (!localStorage.getItem('rss-data')) {
localStorage.setItem('rss-data','{}');
}
let {access_token, domain} = JSON.parse(localStorage.getItem('rss-data'));
// if no access token in storage, no code in url
// hide app, show login prompt
if (!getUrlParameter('code') && !access_token) {
document.getElementById('convert').hidden = true;
document.getElementById('login').hidden = false;
}
// if no access token in storage, code in url
// send the code parameter to the server to get an access token
// store the result in localStorage, reload the page
if (getUrlParameter('code') && !access_token) {
fetch(`/api/request-token/?code=${getUrlParameter('code')}`)
.then((resp) => resp.json())
.then(data => {
localStorage.setItem('rss-data',JSON.stringify(data));
// reload without url parameters
window.location.href = window.location.origin + window.location.pathname;
});
}
// if we have an access token, then we can render our app
if (JSON.parse(localStorage.getItem('rss-data')).access_token) {
let {access_token, domain} = JSON.parse(localStorage.getItem('rss-data'));
document.getElementById('login').hidden = true;
document.getElementById('login-confirmed').innerHTML = `<p>Welcome! You are logged in via your <strong>${domain}</strong> account. <a href="#" onclick="logOut()">Click here</a> to log out.</p>`;
document.getElementById('convert').hidden = false;
}
function logOut() {
localStorage.removeItem('rss-data');
window.location = window.location;
}
</script>
</body>
</html>