Merge branch 'main' into remove-dead-code

This commit is contained in:
Felix Ableitner 2020-08-11 19:50:02 +02:00
commit 4ab97fad4d
21 changed files with 154 additions and 17 deletions

2
ansible/VERSION vendored
View file

@ -1 +1 @@
v0.7.47
v0.7.49

View file

@ -51,9 +51,6 @@ server {
# Upload limit for pictrs
client_max_body_size 20M;
# Rate limit
limit_req zone=lemmy_ratelimit burst=30 nodelay;
location / {
proxy_pass http://0.0.0.0:8536;
proxy_set_header X-Real-IP $remote_addr;
@ -67,6 +64,9 @@ server {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Rate limit
limit_req zone=lemmy_ratelimit burst=30 nodelay;
}
# Redirect pictshare images to pictrs
@ -74,6 +74,14 @@ server {
return 301 /pictrs/image/$1;
}
# Separate location block to disable rate limiting for images
location /pictrs {
proxy_pass http://0.0.0.0:8536/pictrs;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /iframely/ {
proxy_pass http://0.0.0.0:8061/;
proxy_set_header X-Real-IP $remote_addr;

View file

@ -6,7 +6,7 @@ pushd ../../server/ || exit
cargo build &
popd || exit
if [ "$1" = "-yarn" ]; then
if [ "$1" != "--no-yarn-build" ]; then
pushd ../../ui/ || exit
yarn
yarn build

View file

@ -12,7 +12,7 @@ services:
restart: always
lemmy:
image: dessalines/lemmy:v0.7.47
image: dessalines/lemmy:v0.7.49
ports:
- "127.0.0.1:8536:8536"
restart: always

View file

@ -1,5 +1,5 @@
#!/bin/sh
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
docker tag dessalines/lemmy:travis \
dessalines/lemmy:v0.7.47
docker push dessalines/lemmy:v0.7.47
dessalines/lemmy:v0.7.49
docker push dessalines/lemmy:v0.7.49

View file

@ -129,6 +129,20 @@ impl Settings {
fs::read_to_string(CONFIG_FILE)
}
pub fn get_allowed_instances(&self) -> Vec<String> {
let mut allowed_instances: Vec<String> = self
.federation
.allowed_instances
.split(',')
.map(|d| d.to_string())
.collect();
// The defaults.hjson config always returns a [""]
allowed_instances.retain(|d| !d.eq(""));
allowed_instances
}
pub fn save_config_file(data: &str) -> Result<String, Error> {
fs::write(CONFIG_FILE, data)?;

View file

@ -130,6 +130,7 @@ pub struct GetSiteResponse {
pub online: usize,
version: String,
my_user: Option<User_>,
federated_instances: Vec<String>,
}
#[derive(Serialize, Deserialize)]
@ -433,6 +434,7 @@ impl Perform for Oper<GetSite> {
online,
version: version::VERSION.to_string(),
my_user,
federated_instances: Settings::get().get_allowed_instances(),
})
}
}
@ -659,6 +661,7 @@ impl Perform for Oper<TransferSite> {
online: 0,
version: version::VERSION.to_string(),
my_user: Some(user),
federated_instances: Settings::get().get_allowed_instances(),
})
}
}

View file

@ -76,12 +76,8 @@ fn check_is_apub_id_valid(apub_id: &Url) -> Result<(), LemmyError> {
return Err(anyhow!("invalid apub id scheme: {:?}", apub_id.scheme()).into());
}
let mut allowed_instances: Vec<String> = Settings::get()
.federation
.allowed_instances
.split(',')
.map(|d| d.to_string())
.collect();
let mut allowed_instances: Vec<String> = Settings::get().get_allowed_instances();
// need to allow this explicitly because apub activities might contain objects from our local
// instance. replace is needed to remove the port in our federation test setup.
let settings = Settings::get();

View file

@ -40,7 +40,8 @@ pub fn config(cfg: &mut web::ServiceConfig) {
)
.route("/search", web::get().to(index))
.route("/sponsors", web::get().to(index))
.route("/password_change/{token}", web::get().to(index));
.route("/password_change/{token}", web::get().to(index))
.route("/instances", web::get().to(index));
}
async fn index() -> Result<NamedFile, Error> {

View file

@ -1 +1 @@
pub const VERSION: &str = "v0.7.47";
pub const VERSION: &str = "v0.7.49";

View file

@ -48,6 +48,7 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
banned: [],
online: null,
version: null,
federated_instances: null,
},
siteConfigForm: {
config_hjson: null,

View file

@ -51,6 +51,11 @@ export class Footer extends Component<any, FooterState> {
{i18n.t('modlog')}
</Link>
</li>
<li class="nav-item">
<Link class="nav-link" to="/instances">
{i18n.t('instances')}
</Link>
</li>
<li class="nav-item">
<a class="nav-link" href={'/docs/index.html'}>
{i18n.t('docs')}

98
ui/src/components/instances.tsx vendored Normal file
View file

@ -0,0 +1,98 @@
import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import {
UserOperation,
WebSocketJsonResponse,
GetSiteResponse,
} from '../interfaces';
import { WebSocketService } from '../services';
import { wsJsonToRes, toast } from '../utils';
import { i18n } from '../i18next';
interface InstancesState {
loading: boolean;
siteRes: GetSiteResponse;
}
export class Instances extends Component<any, InstancesState> {
private subscription: Subscription;
private emptyState: InstancesState = {
loading: true,
siteRes: undefined,
};
constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
this.subscription = WebSocketService.Instance.subject
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
.subscribe(
msg => this.parseMessage(msg),
err => console.error(err),
() => console.log('complete')
);
WebSocketService.Instance.getSite();
}
componentWillUnmount() {
this.subscription.unsubscribe();
}
get documentTitle(): string {
if (this.state.siteRes) {
return `${i18n.t('instances')} - ${this.state.siteRes.site.name}`;
} else {
return 'Lemmy';
}
}
render() {
return (
<div class="container">
<Helmet title={this.documentTitle} />
{this.state.loading ? (
<h5 class="">
<svg class="icon icon-spinner spin">
<use xlinkHref="#icon-spinner"></use>
</svg>
</h5>
) : (
<div>
<h5>{i18n.t('linked_instances')}</h5>
{this.state.siteRes &&
this.state.siteRes.federated_instances.length ? (
<ul>
{this.state.siteRes.federated_instances.map(i => (
<li>
<a href={`https://${i}`} target="_blank" rel="noopener">
{i}
</a>
</li>
))}
</ul>
) : (
<div>{i18n.t('none_found')}</div>
)}
</div>
)}
</div>
);
}
parseMessage(msg: WebSocketJsonResponse) {
console.log(msg);
let res = wsJsonToRes(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
} else if (res.op == UserOperation.GetSite) {
let data = res.data as GetSiteResponse;
this.state.siteRes = data;
this.state.loading = false;
this.setState(this.state);
}
}
}

View file

@ -114,6 +114,7 @@ export class Main extends Component<any, MainState> {
banned: [],
online: null,
version: null,
federated_instances: null,
},
showEditSite: false,
loading: true,

View file

@ -82,6 +82,7 @@ export class Navbar extends Component<any, NavbarState> {
banned: [],
online: null,
version: null,
federated_instances: null,
},
searchParam: '',
toggleSearch: false,

View file

@ -97,6 +97,7 @@ export class Post extends Component<any, PostState> {
},
online: null,
version: null,
federated_instances: undefined,
},
};

View file

@ -19,6 +19,7 @@ interface SilverUser {
}
let general = [
'Brendan',
'mexicanhalloween',
'William Moore',
'Rachel Schmitz',

View file

@ -142,6 +142,7 @@ export class User extends Component<any, UserState> {
},
version: undefined,
my_user: undefined,
federated_instances: undefined,
},
};

2
ui/src/index.tsx vendored
View file

@ -19,6 +19,7 @@ import { AdminSettings } from './components/admin-settings';
import { Inbox } from './components/inbox';
import { Search } from './components/search';
import { Sponsors } from './components/sponsors';
import { Instances } from './components/instances';
import { Symbols } from './components/symbols';
import { i18n } from './i18next';
@ -89,6 +90,7 @@ class Index extends Component<any, any> {
path={`/password_change/:token`}
component={PasswordChange}
/>
<Route path={`/instances`} component={Instances} />
</Switch>
<Symbols />
</div>

View file

@ -867,6 +867,7 @@ export interface GetSiteResponse {
online: number;
version: string;
my_user?: User;
federated_instances: Array<string>;
}
export interface SiteResponse {

View file

@ -294,5 +294,8 @@
"invalid_post_title": "Invalid post title",
"invalid_url": "Invalid URL.",
"play_captcha_audio": "Play Captcha Audio",
"bio": "Bio"
"bio": "Bio",
"instances": "Instances",
"linked_instances": "Linked Instances",
"none_found": "None found."
}