commit
633caad92f
6 changed files with 188 additions and 5 deletions
139
INSTALLATION.md
Normal file
139
INSTALLATION.md
Normal file
|
@ -0,0 +1,139 @@
|
|||
# Installation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need a Twitter API key to make BirdsiteLIVE working. First create an **Standalone App** in the [Twitter developer portal](https://developer.twitter.com/en/portal/projects-and-apps) and retrieve the API Key and API Secret Key.
|
||||
|
||||
## Server prerequisites
|
||||
|
||||
Your instance will need [docker](https://docs.docker.com/engine/install/) and [docker-compose](https://docs.docker.com/compose/install/) installed and working.
|
||||
|
||||
## Setup
|
||||
|
||||
Download the [docker-compose file](https://github.com/NicolasConstant/BirdsiteLive/blob/master/docker-compose.yml):
|
||||
|
||||
```
|
||||
sudo curl -L https://raw.githubusercontent.com/NicolasConstant/BirdsiteLive/master/docker-compose.yml -o docker-compose.yml
|
||||
```
|
||||
|
||||
Then edit file:
|
||||
|
||||
```
|
||||
sudo nano docker-compose.yml
|
||||
```
|
||||
|
||||
### Attributes to change in the docker-compose file
|
||||
|
||||
#### Personal info
|
||||
|
||||
* `Instance:Domain` the domain name you'll be using, for example use `birdsite.live` for the URL `https://birdsite.live`
|
||||
* `Instance:AdminEmail` the admin's email, will be displayed in the instance /.well-known/nodeinfo endpoint
|
||||
* `Twitter:ConsumerKey` the Twitter API key
|
||||
* `Twitter:ConsumerSecret` the Twitter API secret key
|
||||
|
||||
#### Database credentials
|
||||
|
||||
The database credentials must be changed the same way in the **server** and **db** section.
|
||||
|
||||
* database name:
|
||||
* `Db:Name`
|
||||
* `POSTGRES_DB`
|
||||
* database user name:
|
||||
* `Db:User`
|
||||
* `POSTGRES_USER`
|
||||
* database user password:
|
||||
* `Db:Password`
|
||||
* `POSTGRES_PASSWORD`
|
||||
|
||||
## Startup
|
||||
|
||||
Launch the app with:
|
||||
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
By default the app will be available on the port 5000
|
||||
|
||||
## Nginx
|
||||
|
||||
On a Debian based distrib:
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install nginx
|
||||
```
|
||||
|
||||
Check nginx status:
|
||||
|
||||
```
|
||||
sudo systemctl status nginx
|
||||
```
|
||||
|
||||
### Create nginx configuration
|
||||
|
||||
Create your nginx configuration
|
||||
|
||||
```
|
||||
sudo nano /etc/nginx/sites-enabled/{your-domain-name.com}
|
||||
```
|
||||
|
||||
And fill your service block as follow:
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
server_name {your-domain-name.com};
|
||||
location / {
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection keep-alive;
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Save and start/restart your Nginx service
|
||||
|
||||
```
|
||||
sudo service nginx start
|
||||
# or restart it if its already started
|
||||
sudo service nginx restart
|
||||
```
|
||||
|
||||
### Secure your hosted application with SSL
|
||||
|
||||
After having a domain name pointing to your instance, install and setup certbot:
|
||||
|
||||
```
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d {your-domain-name.com}
|
||||
```
|
||||
|
||||
Make sure you're redirecting all traffic to https when asked.
|
||||
|
||||
Finally check that the auto-revewal will work as espected:
|
||||
|
||||
```
|
||||
sudo certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Set the firewall
|
||||
|
||||
Make sure you're securing your firewall correctly:
|
||||
|
||||
```
|
||||
sudo ufw app list
|
||||
sudo ufw allow 'Nginx Full'
|
||||
sudo ufw allow 22/tcp
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw enable
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
You should now have an up and running BirdsiteLIVE instance!
|
27
README.md
27
README.md
|
@ -1,4 +1,27 @@
|
|||
![Test](https://github.com/NicolasConstant/BirdsiteLive/workflows/.NET%20Core/badge.svg?branch=master&event=push)
|
||||
|
||||
# BirdsiteLive
|
||||
An ethical ActivityPub bridge from Twitter
|
||||
# BirdsiteLIVE
|
||||
|
||||
## About
|
||||
|
||||
BirdsiteLIVE is an ActivityPub bridge from Twitter, it's mostly a pet project/playground for me to handle ActivityPub concepts. Feel free to deploy your own instance (especially if you plan to follow a lot of users) since it use a proper Twitter API key and therefore will have limited calls ceiling (it won't scale, and it's by design).
|
||||
|
||||
## State of development
|
||||
|
||||
The code is pretty messy and far from a good state, since it's a playground for me the aim was to understand some AP concepts, not provide a good state-of-the-art codebase. But I might refactor it to make it cleaner.
|
||||
|
||||
## Official instance
|
||||
|
||||
You can find an official (and temporary) instance here: [beta.birdsite.live](https://beta.birdsite.live). This instance can disapear at any time, if you want a long term instance you should install your own or use another one.
|
||||
|
||||
## Installation
|
||||
|
||||
Please follow [those instructions](https://github.com/NicolasConstant/BirdsiteLive/blob/master/INSTALLATION.md)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the AGPLv3 License - see [LICENSE](https://github.com/NicolasConstant/BirdsiteLive/blob/master/LICENSE) for details
|
||||
|
||||
## Contact
|
||||
|
||||
You can contact me via ActivityPub [here](https://social.nicolas-constant.com/NicolasConstant).
|
||||
|
|
|
@ -36,21 +36,31 @@ namespace BirdsiteLive.Controllers
|
|||
}
|
||||
#endregion
|
||||
|
||||
[Route("/users")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
var r = Request.Headers["Accept"].First();
|
||||
if (r.Contains("application/activity+json")) return NotFound();
|
||||
return View("UserNotFound");
|
||||
}
|
||||
|
||||
[Route("/@{id}")]
|
||||
[Route("/users/{id}")]
|
||||
public IActionResult Index(string id)
|
||||
{
|
||||
var user = _twitterService.GetUser(id);
|
||||
if (user == null) return NotFound();
|
||||
|
||||
var r = Request.Headers["Accept"].First();
|
||||
if (r.Contains("application/activity+json"))
|
||||
{
|
||||
if (user == null) return NotFound();
|
||||
var apUser = _userService.GetUser(user);
|
||||
var jsonApUser = JsonConvert.SerializeObject(apUser);
|
||||
return Content(jsonApUser, "application/activity+json; charset=utf-8");
|
||||
}
|
||||
|
||||
if (user == null) return View("UserNotFound");
|
||||
|
||||
var displayableUser = new DisplayTwitterUser
|
||||
{
|
||||
Name = user.Name,
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</div>*@
|
||||
<div class="form-group">
|
||||
@*<label for="exampleInputPassword1">Password</label>*@
|
||||
<input type="text" class="form-control col-4 mx-auto" id="handle" name="handle" autocomplete="off" placeholder="Twitter Handle">
|
||||
<input type="text" class="form-control col-8 col-sm-8 col-md-6 col-lg-4 mx-auto" id="handle" name="handle" autocomplete="off" placeholder="Twitter Handle">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Show</button>
|
||||
</form>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
}
|
||||
|
||||
|
||||
<div class="col-6 mx-auto">
|
||||
<div class="col-12 col-sm-10 col-md-8 col-lg-6 mx-auto">
|
||||
<a href="@ViewData.Model.Url" class="nounderline" title="@ViewData.Model.Url">
|
||||
@*<div class="profile" style="background-image: url('@ViewData.Model.ProfileBannerURL');">*@
|
||||
<div class="profile">
|
||||
|
|
11
src/BirdsiteLive/Views/Users/UserNotFound.cshtml
Normal file
11
src/BirdsiteLive/Views/Users/UserNotFound.cshtml
Normal file
|
@ -0,0 +1,11 @@
|
|||
@{
|
||||
ViewData["Title"] = "User";
|
||||
}
|
||||
|
||||
<div class="col-12 col-sm-10 col-md-8 col-lg-6 mx-auto text-center">
|
||||
<h3>User not found</h3>
|
||||
|
||||
<a href="/" class="btn btn-primary">
|
||||
Back
|
||||
</a>
|
||||
</div>
|
Reference in a new issue