Merge branch 'fixes' into 'master'
More fixes See merge request framasoft/mobilizon!889
This commit is contained in:
commit
de7ad98cd5
|
@ -25,9 +25,9 @@ config :mobilizon, :instance,
|
||||||
allow_relay: true,
|
allow_relay: true,
|
||||||
federating: true,
|
federating: true,
|
||||||
remote_limit: 100_000,
|
remote_limit: 100_000,
|
||||||
upload_limit: 10_000_000,
|
upload_limit: 10_485_760,
|
||||||
avatar_upload_limit: 2_000_000,
|
avatar_upload_limit: 2_097_152,
|
||||||
banner_upload_limit: 4_000_000,
|
banner_upload_limit: 4_194_304,
|
||||||
remove_orphan_uploads: true,
|
remove_orphan_uploads: true,
|
||||||
orphan_upload_grace_period_hours: 48,
|
orphan_upload_grace_period_hours: 48,
|
||||||
remove_unconfirmed_users: true,
|
remove_unconfirmed_users: true,
|
||||||
|
|
|
@ -1,15 +1,35 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<figure class="image" v-if="imageSrc">
|
<figure class="image" v-if="imageSrc && !imagePreviewLoadingError">
|
||||||
<img :src="imageSrc" />
|
<img :src="imageSrc" @error="showImageLoadingError" />
|
||||||
</figure>
|
</figure>
|
||||||
<figure class="image is-128x128" v-else>
|
<figure class="image is-128x128" v-else>
|
||||||
<div class="image-placeholder">
|
<div
|
||||||
<span class="has-text-centered">{{ textFallback }}</span>
|
class="image-placeholder"
|
||||||
|
:class="{ error: imagePreviewLoadingError }"
|
||||||
|
>
|
||||||
|
<span class="has-text-centered" v-if="imagePreviewLoadingError">{{
|
||||||
|
$t("Error while loading the preview")
|
||||||
|
}}</span>
|
||||||
|
<span class="has-text-centered" v-else>{{ textFallback }}</span>
|
||||||
</div>
|
</div>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<p v-if="pictureFile" class="metadata">
|
||||||
|
<span class="name" :title="pictureFile.name">{{
|
||||||
|
pictureFile.name
|
||||||
|
}}</span>
|
||||||
|
<span class="size">({{ formatBytes(pictureFile.size) }})</span>
|
||||||
|
</p>
|
||||||
|
<p v-if="pictureTooBig" class="picture-too-big">
|
||||||
|
{{
|
||||||
|
$t(
|
||||||
|
"The selected picture is too heavy. You need to select a file smaller than {size}.",
|
||||||
|
{ size: formatBytes(maxSize) }
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
<b-field class="file is-primary">
|
<b-field class="file is-primary">
|
||||||
<b-upload @input="onFileChanged" :accept="accept" class="file-label">
|
<b-upload @input="onFileChanged" :accept="accept" class="file-label">
|
||||||
<span class="file-cta">
|
<span class="file-cta">
|
||||||
|
@ -47,6 +67,10 @@ figure.image {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
border: 2px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: #eee;
|
color: #eee;
|
||||||
|
@ -56,6 +80,27 @@ figure.image {
|
||||||
.action-buttons {
|
.action-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
.file {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadata {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
max-width: 200px;
|
||||||
|
display: block;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.picture-too-big {
|
||||||
|
color: $danger;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -87,30 +132,32 @@ export default class PictureUpload extends Vue {
|
||||||
})
|
})
|
||||||
textFallback!: string;
|
textFallback!: string;
|
||||||
|
|
||||||
imageSrc: string | null = this.defaultImage ? this.defaultImage.url : null;
|
@Prop({ type: Number, required: false, default: 10_485_760 })
|
||||||
|
maxSize!: number;
|
||||||
|
|
||||||
file!: File | null;
|
file!: File | null;
|
||||||
|
|
||||||
mounted(): void {
|
imagePreviewLoadingError = false;
|
||||||
if (this.pictureFile) {
|
|
||||||
this.updatePreview(this.pictureFile);
|
get pictureTooBig(): boolean {
|
||||||
|
return this.pictureFile?.size > this.maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
get imageSrc(): string | null {
|
||||||
|
if (this.pictureFile !== undefined) {
|
||||||
|
if (this.pictureFile === null) return null;
|
||||||
|
try {
|
||||||
|
return URL.createObjectURL(this.pictureFile);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return this.defaultImage ? this.defaultImage.url : null;
|
||||||
|
|
||||||
@Watch("pictureFile")
|
|
||||||
onPictureFileChanged(val: File): void {
|
|
||||||
this.updatePreview(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Watch("defaultImage")
|
|
||||||
onDefaultImageChange(defaultImage: IMedia): void {
|
|
||||||
this.imageSrc = defaultImage ? defaultImage.url : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFileChanged(file: File | null): void {
|
onFileChanged(file: File | null): void {
|
||||||
this.$emit("change", file);
|
this.$emit("change", file);
|
||||||
|
|
||||||
this.updatePreview(file);
|
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,13 +165,23 @@ export default class PictureUpload extends Vue {
|
||||||
this.onFileChanged(null);
|
this.onFileChanged(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updatePreview(file?: File | null) {
|
@Watch("imageSrc")
|
||||||
if (file) {
|
resetImageLoadingError(): void {
|
||||||
this.imageSrc = URL.createObjectURL(file);
|
this.imagePreviewLoadingError = false;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.imageSrc = null;
|
showImageLoadingError(): void {
|
||||||
|
this.imagePreviewLoadingError = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://gist.github.com/zentala/1e6f72438796d74531803cc3833c039c
|
||||||
|
formatBytes(bytes: number, decimals: number): string {
|
||||||
|
if (bytes == 0) return "0 Bytes";
|
||||||
|
const k = 1024,
|
||||||
|
dm = decimals || 2,
|
||||||
|
sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
|
||||||
|
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -75,6 +75,11 @@ export const CONFIG = gql`
|
||||||
label
|
label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uploadLimits {
|
||||||
|
default
|
||||||
|
avatar
|
||||||
|
banner
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -979,5 +979,10 @@
|
||||||
"Personal feeds": "Personal feeds",
|
"Personal feeds": "Personal feeds",
|
||||||
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.",
|
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.",
|
||||||
"The event will show as attributed to this profile.": "The event will show as attributed to this profile.",
|
"The event will show as attributed to this profile.": "The event will show as attributed to this profile.",
|
||||||
"You may show some members as contacts.": "You may show some members as contacts."
|
"You may show some members as contacts.": "You may show some members as contacts.",
|
||||||
|
"The selected picture is too heavy. You need to select a file smaller than {size}.": "The selected picture is too heavy. You need to select a file smaller than {size}.",
|
||||||
|
"Unable to create the group. One of the pictures may be too heavy.": "Unable to create the group. One of the pictures may be too heavy.",
|
||||||
|
"Unable to update the profile. The avatar picture may be too heavy.": "Unable to update the profile. The avatar picture may be too heavy.",
|
||||||
|
"Unable to create the profile. The avatar picture may be too heavy.": "Unable to create the profile. The avatar picture may be too heavy.",
|
||||||
|
"Error while loading the preview": "Error while loading the preview"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1073,5 +1073,10 @@
|
||||||
"Personal feeds": "Flux personnels",
|
"Personal feeds": "Flux personnels",
|
||||||
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "Ces flux contiennent des informations sur les événements pour lesquels n'importe lequel de vos profils est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux spécifiques à chaque profil sur la page d'édition des profils.",
|
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "Ces flux contiennent des informations sur les événements pour lesquels n'importe lequel de vos profils est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux spécifiques à chaque profil sur la page d'édition des profils.",
|
||||||
"The event will show as attributed to this profile.": "L'événement sera affiché comme attribué à ce profil.",
|
"The event will show as attributed to this profile.": "L'événement sera affiché comme attribué à ce profil.",
|
||||||
"You may show some members as contacts.": "Vous pouvez afficher certain⋅es membres en tant que contacts."
|
"You may show some members as contacts.": "Vous pouvez afficher certain⋅es membres en tant que contacts.",
|
||||||
|
"The selected picture is too heavy. You need to select a file smaller than {size}.": "L'image sélectionnée est trop lourde. Vous devez sélectionner un fichier de moins de {size}.",
|
||||||
|
"Unable to create the group. One of the pictures may be too heavy.": "Impossible de créer le groupe. Une des images est trop lourde.",
|
||||||
|
"Unable to update the profile. The avatar picture may be too heavy.": "Impossible de mettre à jour le profil. L'image d'avatar est probablement trop lourde.",
|
||||||
|
"Unable to create the profile. The avatar picture may be too heavy.": "Impossible de créer le profil. L'image d'avatar est probablement trop lourde.",
|
||||||
|
"Error while loading the preview": "Erreur lors du chargement de l'aperçu"
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,4 +89,9 @@ export interface IConfig {
|
||||||
ldap: boolean;
|
ldap: boolean;
|
||||||
oauthProviders: IOAuthProvider[];
|
oauthProviders: IOAuthProvider[];
|
||||||
};
|
};
|
||||||
|
uploadLimits: {
|
||||||
|
default: number;
|
||||||
|
avatar: number;
|
||||||
|
banner: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
<picture-upload
|
<picture-upload
|
||||||
v-model="avatarFile"
|
v-model="avatarFile"
|
||||||
:defaultImage="identity.avatar"
|
:defaultImage="identity.avatar"
|
||||||
|
:maxSize="avatarMaxSize"
|
||||||
class="picture-upload"
|
class="picture-upload"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -231,6 +232,9 @@ import {
|
||||||
DELETE_FEED_TOKEN,
|
DELETE_FEED_TOKEN,
|
||||||
} from "@/graphql/feed_tokens";
|
} from "@/graphql/feed_tokens";
|
||||||
import { IFeedToken } from "@/types/feedtoken.model";
|
import { IFeedToken } from "@/types/feedtoken.model";
|
||||||
|
import { ServerParseError } from "apollo-link-http-common";
|
||||||
|
import { IConfig } from "@/types/config.model";
|
||||||
|
import { CONFIG } from "@/graphql/config";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
|
@ -256,6 +260,7 @@ import { IFeedToken } from "@/types/feedtoken.model";
|
||||||
this.handleErrors(graphQLErrors);
|
this.handleErrors(graphQLErrors);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config: CONFIG,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class EditIdentity extends mixins(identityEditionMixin) {
|
export default class EditIdentity extends mixins(identityEditionMixin) {
|
||||||
|
@ -263,6 +268,8 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
|
||||||
|
|
||||||
@Prop({ type: String }) identityName!: string;
|
@Prop({ type: String }) identityName!: string;
|
||||||
|
|
||||||
|
config!: IConfig;
|
||||||
|
|
||||||
errors: string[] = [];
|
errors: string[] = [];
|
||||||
|
|
||||||
avatarFile: File | null = null;
|
avatarFile: File | null = null;
|
||||||
|
@ -450,6 +457,10 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get avatarMaxSize(): number | undefined {
|
||||||
|
return this?.config?.uploadLimits?.avatar;
|
||||||
|
}
|
||||||
|
|
||||||
async generateFeedTokens(): Promise<void> {
|
async generateFeedTokens(): Promise<void> {
|
||||||
const newToken = await this.createNewFeedToken();
|
const newToken = await this.createNewFeedToken();
|
||||||
this.identity.feedTokens.push(newToken);
|
this.identity.feedTokens.push(newToken);
|
||||||
|
@ -528,6 +539,21 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
|
||||||
private handleError(err: any) {
|
private handleError(err: any) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
||||||
|
if (err?.networkError?.name === "ServerParseError") {
|
||||||
|
const error = err?.networkError as ServerParseError;
|
||||||
|
|
||||||
|
if (error?.response?.status === 413) {
|
||||||
|
const errorMessage = this.isUpdate
|
||||||
|
? this.$t(
|
||||||
|
"Unable to update the profile. The avatar picture may be too heavy."
|
||||||
|
)
|
||||||
|
: this.$t(
|
||||||
|
"Unable to create the profile. The avatar picture may be too heavy."
|
||||||
|
);
|
||||||
|
this.errors.push(errorMessage as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (err.graphQLErrors !== undefined) {
|
if (err.graphQLErrors !== undefined) {
|
||||||
err.graphQLErrors.forEach(({ message }: { message: string }) => {
|
err.graphQLErrors.forEach(({ message }: { message: string }) => {
|
||||||
this.$notifier.error(message);
|
this.$notifier.error(message);
|
||||||
|
|
|
@ -58,12 +58,20 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<b>{{ $t("Avatar") }}</b>
|
<b>{{ $t("Avatar") }}</b>
|
||||||
<picture-upload :textFallback="$t('Avatar')" v-model="avatarFile" />
|
<picture-upload
|
||||||
|
:textFallback="$t('Avatar')"
|
||||||
|
v-model="avatarFile"
|
||||||
|
:maxSize="avatarMaxSize"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<b>{{ $t("Banner") }}</b>
|
<b>{{ $t("Banner") }}</b>
|
||||||
<picture-upload :textFallback="$t('Banner')" v-model="bannerFile" />
|
<picture-upload
|
||||||
|
:textFallback="$t('Banner')"
|
||||||
|
v-model="bannerFile"
|
||||||
|
:maxSize="bannerMaxSize"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="button is-primary" native-type="submit">
|
<button class="button is-primary" native-type="submit">
|
||||||
|
@ -84,6 +92,10 @@ import { MemberRole } from "@/types/enums";
|
||||||
import RouteName from "../../router/name";
|
import RouteName from "../../router/name";
|
||||||
import { convertToUsername } from "../../utils/username";
|
import { convertToUsername } from "../../utils/username";
|
||||||
import PictureUpload from "../../components/PictureUpload.vue";
|
import PictureUpload from "../../components/PictureUpload.vue";
|
||||||
|
import { ErrorResponse } from "apollo-link-error";
|
||||||
|
import { ServerParseError } from "apollo-link-http-common";
|
||||||
|
import { CONFIG } from "@/graphql/config";
|
||||||
|
import { IConfig } from "@/types/config.model";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
|
@ -93,6 +105,7 @@ import PictureUpload from "../../components/PictureUpload.vue";
|
||||||
currentActor: {
|
currentActor: {
|
||||||
query: CURRENT_ACTOR_CLIENT,
|
query: CURRENT_ACTOR_CLIENT,
|
||||||
},
|
},
|
||||||
|
config: CONFIG,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class CreateGroup extends mixins(IdentityEditionMixin) {
|
export default class CreateGroup extends mixins(IdentityEditionMixin) {
|
||||||
|
@ -100,6 +113,8 @@ export default class CreateGroup extends mixins(IdentityEditionMixin) {
|
||||||
|
|
||||||
group = new Group();
|
group = new Group();
|
||||||
|
|
||||||
|
config!: IConfig;
|
||||||
|
|
||||||
avatarFile: File | null = null;
|
avatarFile: File | null = null;
|
||||||
|
|
||||||
bannerFile: File | null = null;
|
bannerFile: File | null = null;
|
||||||
|
@ -110,6 +125,7 @@ export default class CreateGroup extends mixins(IdentityEditionMixin) {
|
||||||
|
|
||||||
async createGroup(): Promise<void> {
|
async createGroup(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
this.errors = [];
|
||||||
await this.$apollo.mutate({
|
await this.$apollo.mutate({
|
||||||
mutation: CREATE_GROUP,
|
mutation: CREATE_GROUP,
|
||||||
variables: this.buildVariables(),
|
variables: this.buildVariables(),
|
||||||
|
@ -154,6 +170,14 @@ export default class CreateGroup extends mixins(IdentityEditionMixin) {
|
||||||
return window.location.hostname;
|
return window.location.hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get avatarMaxSize(): number | undefined {
|
||||||
|
return this?.config?.uploadLimits?.avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
get bannerMaxSize(): number | undefined {
|
||||||
|
return this?.config?.uploadLimits?.banner;
|
||||||
|
}
|
||||||
|
|
||||||
@Watch("group.name")
|
@Watch("group.name")
|
||||||
updateUsername(groupName: string): void {
|
updateUsername(groupName: string): void {
|
||||||
this.group.preferredUsername = convertToUsername(groupName);
|
this.group.preferredUsername = convertToUsername(groupName);
|
||||||
|
@ -194,9 +218,22 @@ export default class CreateGroup extends mixins(IdentityEditionMixin) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleError(err: any) {
|
private handleError(err: ErrorResponse) {
|
||||||
|
if (err?.networkError?.name === "ServerParseError") {
|
||||||
|
const error = err?.networkError as ServerParseError;
|
||||||
|
|
||||||
|
if (error?.response?.status === 413) {
|
||||||
|
this.errors.push(
|
||||||
|
this.$t(
|
||||||
|
"Unable to create the group. One of the pictures may be too heavy."
|
||||||
|
) as string
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
this.errors.push(
|
this.errors.push(
|
||||||
...err.graphQLErrors.map(({ message }: { message: string }) => message)
|
...(err.graphQLErrors || []).map(
|
||||||
|
({ message }: { message: string }) => message
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
:textFallback="$t('Avatar')"
|
:textFallback="$t('Avatar')"
|
||||||
v-model="avatarFile"
|
v-model="avatarFile"
|
||||||
:defaultImage="group.avatar"
|
:defaultImage="group.avatar"
|
||||||
|
:maxSize="avatarMaxSize"
|
||||||
/>
|
/>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
:textFallback="$t('Banner')"
|
:textFallback="$t('Banner')"
|
||||||
v-model="bannerFile"
|
v-model="bannerFile"
|
||||||
:defaultImage="group.banner"
|
:defaultImage="group.banner"
|
||||||
|
:maxSize="bannerMaxSize"
|
||||||
/>
|
/>
|
||||||
</b-field>
|
</b-field>
|
||||||
<p class="label">{{ $t("Group visibility") }}</p>
|
<p class="label">{{ $t("Group visibility") }}</p>
|
||||||
|
@ -158,6 +160,9 @@
|
||||||
}}</b-button>
|
}}</b-button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<b-message type="is-danger" v-for="(value, index) in errors" :key="index">
|
||||||
|
{{ value }}
|
||||||
|
</b-message>
|
||||||
</section>
|
</section>
|
||||||
<b-message v-else>
|
<b-message v-else>
|
||||||
{{ $t("You are not an administrator for this group.") }}
|
{{ $t("You are not an administrator for this group.") }}
|
||||||
|
@ -177,6 +182,10 @@ import RouteName from "../../router/name";
|
||||||
import { UPDATE_GROUP, DELETE_GROUP } from "../../graphql/group";
|
import { UPDATE_GROUP, DELETE_GROUP } from "../../graphql/group";
|
||||||
import { IGroup, usernameWithDomain } from "../../types/actor";
|
import { IGroup, usernameWithDomain } from "../../types/actor";
|
||||||
import { Address, IAddress } from "../../types/address.model";
|
import { Address, IAddress } from "../../types/address.model";
|
||||||
|
import { CONFIG } from "@/graphql/config";
|
||||||
|
import { IConfig } from "@/types/config.model";
|
||||||
|
import { ErrorResponse } from "apollo-link-error";
|
||||||
|
import { ServerParseError } from "apollo-link-http-common";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
|
@ -184,14 +193,21 @@ import { Address, IAddress } from "../../types/address.model";
|
||||||
PictureUpload,
|
PictureUpload,
|
||||||
editor: () => import("../../components/Editor.vue"),
|
editor: () => import("../../components/Editor.vue"),
|
||||||
},
|
},
|
||||||
|
apollo: {
|
||||||
|
config: CONFIG,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
export default class GroupSettings extends mixins(GroupMixin) {
|
export default class GroupSettings extends mixins(GroupMixin) {
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
RouteName = RouteName;
|
RouteName = RouteName;
|
||||||
|
|
||||||
|
config!: IConfig;
|
||||||
|
|
||||||
newMemberUsername = "";
|
newMemberUsername = "";
|
||||||
|
|
||||||
|
errors: string[] = [];
|
||||||
|
|
||||||
avatarFile: File | null = null;
|
avatarFile: File | null = null;
|
||||||
|
|
||||||
bannerFile: File | null = null;
|
bannerFile: File | null = null;
|
||||||
|
@ -205,12 +221,16 @@ export default class GroupSettings extends mixins(GroupMixin) {
|
||||||
showCopiedTooltip = false;
|
showCopiedTooltip = false;
|
||||||
|
|
||||||
async updateGroup(): Promise<void> {
|
async updateGroup(): Promise<void> {
|
||||||
const variables = this.buildVariables();
|
try {
|
||||||
await this.$apollo.mutate<{ updateGroup: IGroup }>({
|
const variables = this.buildVariables();
|
||||||
mutation: UPDATE_GROUP,
|
await this.$apollo.mutate<{ updateGroup: IGroup }>({
|
||||||
variables,
|
mutation: UPDATE_GROUP,
|
||||||
});
|
variables,
|
||||||
this.$notifier.success(this.$t("Group settings saved") as string);
|
});
|
||||||
|
this.$notifier.success(this.$t("Group settings saved") as string);
|
||||||
|
} catch (err) {
|
||||||
|
this.handleError(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeleteGroup(): void {
|
confirmDeleteGroup(): void {
|
||||||
|
@ -299,5 +319,32 @@ export default class GroupSettings extends mixins(GroupMixin) {
|
||||||
get currentAddress(): IAddress {
|
get currentAddress(): IAddress {
|
||||||
return new Address(this.group.physicalAddress);
|
return new Address(this.group.physicalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get avatarMaxSize(): number | undefined {
|
||||||
|
return this?.config?.uploadLimits?.avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
get bannerMaxSize(): number | undefined {
|
||||||
|
return this?.config?.uploadLimits?.banner;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleError(err: ErrorResponse) {
|
||||||
|
if (err?.networkError?.name === "ServerParseError") {
|
||||||
|
const error = err?.networkError as ServerParseError;
|
||||||
|
|
||||||
|
if (error?.response?.status === 413) {
|
||||||
|
this.errors.push(
|
||||||
|
this.$t(
|
||||||
|
"Unable to create the group. One of the pictures may be too heavy."
|
||||||
|
) as string
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.errors.push(
|
||||||
|
...(err.graphQLErrors || []).map(
|
||||||
|
({ message }: { message: string }) => message
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -13,7 +13,6 @@ import buildCurrentUserResolver from "@/apollo/user";
|
||||||
import { isServerError } from "@/types/apollo";
|
import { isServerError } from "@/types/apollo";
|
||||||
import { AUTH_ACCESS_TOKEN } from "@/constants";
|
import { AUTH_ACCESS_TOKEN } from "@/constants";
|
||||||
import { logout } from "@/utils/auth";
|
import { logout } from "@/utils/auth";
|
||||||
import { SnackbarProgrammatic as Snackbar } from "buefy";
|
|
||||||
import { Socket as PhoenixSocket } from "phoenix";
|
import { Socket as PhoenixSocket } from "phoenix";
|
||||||
import * as AbsintheSocket from "@absinthe/socket";
|
import * as AbsintheSocket from "@absinthe/socket";
|
||||||
import { createAbsintheSocketLink } from "@absinthe/socket-apollo-link";
|
import { createAbsintheSocketLink } from "@absinthe/socket-apollo-link";
|
||||||
|
@ -123,12 +122,7 @@ const errorLink = onError(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (networkError) {
|
if (networkError) {
|
||||||
console.log(`[Network error]: ${networkError}`);
|
console.error(`[Network error]: ${networkError}`);
|
||||||
Snackbar.open({
|
|
||||||
message: "Please refresh the page and retry.",
|
|
||||||
type: "is-danger",
|
|
||||||
position: "is-bottom",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -102,6 +102,12 @@ export const configMock = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
slogan: null,
|
slogan: null,
|
||||||
|
uploadLimits: {
|
||||||
|
__typename: "UploadLimits",
|
||||||
|
default: 10_000_000,
|
||||||
|
avatar: 2_000_000,
|
||||||
|
banner: 4_000_000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -654,7 +654,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
||||||
@spec make_actor_from_nickname(String.t()) :: {:ok, %Actor{}} | {:error, any()}
|
@spec make_actor_from_nickname(String.t()) :: {:ok, %Actor{}} | {:error, any()}
|
||||||
def make_actor_from_nickname(nickname) do
|
def make_actor_from_nickname(nickname) do
|
||||||
case WebFinger.finger(nickname) do
|
case WebFinger.finger(nickname) do
|
||||||
{:ok, %{"url" => url}} when not is_nil(url) ->
|
{:ok, url} when is_binary(url) ->
|
||||||
make_actor_from_url(url)
|
make_actor_from_url(url)
|
||||||
|
|
||||||
_e ->
|
_e ->
|
||||||
|
|
|
@ -17,7 +17,8 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
||||||
def fetch(url, options \\ []) do
|
def fetch(url, options \\ []) do
|
||||||
on_behalf_of = Keyword.get(options, :on_behalf_of, Relay.get_actor())
|
on_behalf_of = Keyword.get(options, :on_behalf_of, Relay.get_actor())
|
||||||
|
|
||||||
with date <- Signature.generate_date_header(),
|
with false <- address_invalid(url),
|
||||||
|
date <- Signature.generate_date_header(),
|
||||||
headers <-
|
headers <-
|
||||||
[{:Accept, "application/activity+json"}]
|
[{:Accept, "application/activity+json"}]
|
||||||
|> maybe_date_fetch(date)
|
|> maybe_date_fetch(date)
|
||||||
|
@ -38,6 +39,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
||||||
|
|
||||||
{:ok, %Tesla.Env{} = res} ->
|
{:ok, %Tesla.Env{} = res} ->
|
||||||
{:error, res}
|
{:error, res}
|
||||||
|
|
||||||
|
{:error, err} ->
|
||||||
|
{:error, err}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,4 +94,12 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
||||||
{:error, err}
|
{:error, err}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec address_invalid(String.t()) :: false | {:error, :invalid_url}
|
||||||
|
defp address_invalid(address) do
|
||||||
|
with %URI{host: host, scheme: scheme} <- URI.parse(address),
|
||||||
|
true <- is_nil(host) or is_nil(scheme) do
|
||||||
|
{:error, :invalid_url}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -127,7 +127,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
|
||||||
do: process_collection(first, on_behalf_of)
|
do: process_collection(first, on_behalf_of)
|
||||||
|
|
||||||
defp process_collection(%{"type" => "OrderedCollection", "first" => first}, on_behalf_of)
|
defp process_collection(%{"type" => "OrderedCollection", "first" => first}, on_behalf_of)
|
||||||
when is_bitstring(first) do
|
when is_binary(first) do
|
||||||
Logger.debug("OrderedCollection has a first property pointing to an URI")
|
Logger.debug("OrderedCollection has a first property pointing to an URI")
|
||||||
|
|
||||||
with {:ok, data} <- Fetcher.fetch(first, on_behalf_of: on_behalf_of) do
|
with {:ok, data} <- Fetcher.fetch(first, on_behalf_of: on_behalf_of) do
|
||||||
|
|
|
@ -126,7 +126,7 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp fetch_object(object) when is_bitstring(object), do: {object, object}
|
defp fetch_object(object) when is_binary(object), do: {object, object}
|
||||||
|
|
||||||
@spec fetch_actor(String.t()) :: {:ok, String.t()} | {:error, String.t()}
|
@spec fetch_actor(String.t()) :: {:ok, String.t()} | {:error, String.t()}
|
||||||
# Dirty hack
|
# Dirty hack
|
||||||
|
@ -159,7 +159,7 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
|
||||||
@spec finger_actor(String.t()) :: {:ok, String.t()} | {:error, String.t()}
|
@spec finger_actor(String.t()) :: {:ok, String.t()} | {:error, String.t()}
|
||||||
defp finger_actor(nickname) do
|
defp finger_actor(nickname) do
|
||||||
case WebFinger.finger(nickname) do
|
case WebFinger.finger(nickname) do
|
||||||
{:ok, %{"url" => url}} when not is_nil(url) ->
|
{:ok, url} when is_binary(url) ->
|
||||||
{:ok, url}
|
{:ok, url}
|
||||||
|
|
||||||
_e ->
|
_e ->
|
||||||
|
|
|
@ -26,7 +26,7 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do
|
||||||
# Some implementations send the actor URI as the actor field, others send the entire actor object,
|
# Some implementations send the actor URI as the actor field, others send the entire actor object,
|
||||||
# so figure out what the actor's URI is based on what we have.
|
# so figure out what the actor's URI is based on what we have.
|
||||||
def get_url(%{"id" => id}), do: id
|
def get_url(%{"id" => id}), do: id
|
||||||
def get_url(id) when is_bitstring(id), do: id
|
def get_url(id) when is_binary(id), do: id
|
||||||
def get_url(ids) when is_list(ids), do: get_url(hd(ids))
|
def get_url(ids) when is_list(ids), do: get_url(hd(ids))
|
||||||
def get_url(_), do: nil
|
def get_url(_), do: nil
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_actor(%{"actor" => %{"id" => id}}) when is_bitstring(id) do
|
def get_actor(%{"actor" => %{"id" => id}}) when is_binary(id) do
|
||||||
id
|
id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_address(map | binary | nil) :: integer | nil
|
@spec get_address(map | binary | nil) :: integer | nil
|
||||||
defp get_address(address_url) when is_bitstring(address_url) do
|
defp get_address(address_url) when is_binary(address_url) do
|
||||||
get_address(%{"id" => address_url})
|
get_address(%{"id" => address_url})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Media do
|
||||||
%{"type" => "Document", "url" => media_url, "name" => name},
|
%{"type" => "Document", "url" => media_url, "name" => name},
|
||||||
actor_id
|
actor_id
|
||||||
)
|
)
|
||||||
when is_bitstring(media_url) do
|
when is_binary(media_url) do
|
||||||
with {:ok, %{body: body}} <- Tesla.get(media_url, opts: @http_options),
|
with {:ok, %{body: body}} <- Tesla.get(media_url, opts: @http_options),
|
||||||
{:ok, %{name: name, url: url, content_type: content_type, size: size}} <-
|
{:ok, %{name: name, url: url, content_type: content_type, size: size}} <-
|
||||||
Upload.store(%{body: body, name: name}),
|
Upload.store(%{body: body, name: name}),
|
||||||
|
|
|
@ -94,7 +94,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp fetch_tag(tag) when is_bitstring(tag), do: [tag_without_hash(tag)]
|
defp fetch_tag(tag) when is_binary(tag), do: [tag_without_hash(tag)]
|
||||||
|
|
||||||
defp tag_without_hash("#" <> tag_title), do: tag_title
|
defp tag_without_hash("#" <> tag_title), do: tag_title
|
||||||
defp tag_without_hash(tag_title), do: tag_title
|
defp tag_without_hash(tag_title), do: tag_title
|
||||||
|
|
|
@ -12,26 +12,37 @@ defmodule Mobilizon.Federation.WebFinger do
|
||||||
alias Mobilizon.Actors.Actor
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Federation.ActivityPub
|
alias Mobilizon.Federation.ActivityPub
|
||||||
alias Mobilizon.Federation.WebFinger.XmlBuilder
|
alias Mobilizon.Federation.WebFinger.XmlBuilder
|
||||||
alias Mobilizon.Service.HTTP.WebfingerClient
|
alias Mobilizon.Service.HTTP.{HostMetaClient, WebfingerClient}
|
||||||
alias Mobilizon.Web.Endpoint
|
alias Mobilizon.Web.Endpoint
|
||||||
alias Mobilizon.Web.Router.Helpers, as: Routes
|
alias Mobilizon.Web.Router.Helpers, as: Routes
|
||||||
require Jason
|
require Jason
|
||||||
require Logger
|
require Logger
|
||||||
|
import SweetXml
|
||||||
|
|
||||||
def host_meta do
|
def host_meta do
|
||||||
base_url = Endpoint.url()
|
base_url = Endpoint.url()
|
||||||
|
%URI{host: host} = URI.parse(base_url)
|
||||||
|
|
||||||
{
|
{
|
||||||
:XRD,
|
:XRD,
|
||||||
%{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
|
%{
|
||||||
{
|
xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0",
|
||||||
:Link,
|
"xmlns:hm": "http://host-meta.net/ns/1.0"
|
||||||
%{
|
},
|
||||||
rel: "lrdd",
|
[
|
||||||
type: "application/xrd+xml",
|
{
|
||||||
template: "#{base_url}/.well-known/webfinger?resource={uri}"
|
:"hm:Host",
|
||||||
|
host
|
||||||
|
},
|
||||||
|
{
|
||||||
|
:Link,
|
||||||
|
%{
|
||||||
|
rel: "lrdd",
|
||||||
|
type: "application/jrd+json",
|
||||||
|
template: "#{base_url}/.well-known/webfinger?resource={uri}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|> XmlBuilder.to_doc()
|
|> XmlBuilder.to_doc()
|
||||||
end
|
end
|
||||||
|
@ -56,29 +67,116 @@ defmodule Mobilizon.Federation.WebFinger do
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec represent_actor(Actor.t()) :: struct()
|
@spec represent_actor(Actor.t()) :: struct()
|
||||||
def represent_actor(actor), do: represent_actor(actor, "JSON")
|
def represent_actor(%Actor{} = actor), do: represent_actor(actor, "JSON")
|
||||||
|
|
||||||
@spec represent_actor(Actor.t(), String.t()) :: struct()
|
@spec represent_actor(Actor.t(), String.t()) :: struct()
|
||||||
def represent_actor(actor, "JSON") do
|
def represent_actor(%Actor{} = actor, "JSON") do
|
||||||
%{
|
links =
|
||||||
"subject" => "acct:#{actor.preferred_username}@#{Endpoint.host()}",
|
[
|
||||||
"aliases" => [actor.url],
|
|
||||||
"links" => [
|
|
||||||
%{"rel" => "self", "type" => "application/activity+json", "href" => actor.url},
|
%{"rel" => "self", "type" => "application/activity+json", "href" => actor.url},
|
||||||
%{
|
|
||||||
"rel" => "https://webfinger.net/rel/profile-page/",
|
|
||||||
"type" => "text/html",
|
|
||||||
"href" => actor.url
|
|
||||||
},
|
|
||||||
%{
|
%{
|
||||||
"rel" => "http://ostatus.org/schema/1.0/subscribe",
|
"rel" => "http://ostatus.org/schema/1.0/subscribe",
|
||||||
"template" => "#{Routes.page_url(Endpoint, :interact, uri: nil)}{uri}"
|
"template" => "#{Routes.page_url(Endpoint, :interact, uri: nil)}{uri}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|> maybe_add_avatar(actor)
|
||||||
|
|> maybe_add_profile_page(actor)
|
||||||
|
|
||||||
|
%{
|
||||||
|
"subject" => "acct:#{actor.preferred_username}@#{Endpoint.host()}",
|
||||||
|
"aliases" => [actor.url],
|
||||||
|
"links" => links
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp webfinger_from_json(doc) do
|
defp maybe_add_avatar(data, %Actor{avatar: avatar}) when not is_nil(avatar) do
|
||||||
|
data ++
|
||||||
|
[
|
||||||
|
%{
|
||||||
|
"rel" => "http://webfinger.net/rel/avatar",
|
||||||
|
"type" => avatar.content_type,
|
||||||
|
"href" => avatar.url
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_add_avatar(data, _actor), do: data
|
||||||
|
|
||||||
|
defp maybe_add_profile_page(data, %Actor{type: :Group, url: url}) do
|
||||||
|
data ++
|
||||||
|
[
|
||||||
|
%{
|
||||||
|
"rel" => "http://webfinger.net/rel/profile-page/",
|
||||||
|
"type" => "text/html",
|
||||||
|
"href" => url
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_add_profile_page(data, _actor), do: data
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Finger an actor to retreive it's ActivityPub ID/URL
|
||||||
|
|
||||||
|
Fetches the Extensible Resource Descriptor endpoint `/.well-known/host-meta` to find the Webfinger endpoint (usually `/.well-known/webfinger?resource=`) with `find_webfinger_endpoint/1` and then performs a Webfinger query to get the ActivityPub ID associated to an actor.
|
||||||
|
"""
|
||||||
|
@spec finger(String.t()) :: {:ok, String.t()} | {:error, atom()}
|
||||||
|
def finger(actor) do
|
||||||
|
actor = String.trim_leading(actor, "@")
|
||||||
|
|
||||||
|
with address when is_binary(address) <- apply_webfinger_endpoint(actor),
|
||||||
|
false <- address_invalid(address),
|
||||||
|
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
||||||
|
WebfingerClient.get(address),
|
||||||
|
{:ok, %{"url" => url}} <- webfinger_from_json(body) do
|
||||||
|
{:ok, url}
|
||||||
|
else
|
||||||
|
e ->
|
||||||
|
Logger.debug("Couldn't finger #{actor}")
|
||||||
|
Logger.debug(inspect(e))
|
||||||
|
{:error, e}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Fetches the Extensible Resource Descriptor endpoint `/.well-known/host-meta` to find the Webfinger endpoint (usually `/.well-known/webfinger?resource=`)
|
||||||
|
"""
|
||||||
|
@spec find_webfinger_endpoint(String.t()) :: String.t()
|
||||||
|
def find_webfinger_endpoint(domain) when is_binary(domain) do
|
||||||
|
with {:ok, %{body: body}} <- fetch_document("http://#{domain}/.well-known/host-meta"),
|
||||||
|
link_template <- find_link_from_template(body) do
|
||||||
|
{:ok, link_template}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec apply_webfinger_endpoint(String.t()) :: String.t() | {:error, :host_not_found}
|
||||||
|
defp apply_webfinger_endpoint(actor) do
|
||||||
|
with {:ok, domain} <- domain_from_federated_actor(actor) do
|
||||||
|
case find_webfinger_endpoint(domain) do
|
||||||
|
{:ok, link_template} ->
|
||||||
|
String.replace(link_template, "{uri}", "acct:#{actor}")
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
"http://#{domain}/.well-known/webfinger?resource=acct:#{actor}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec domain_from_federated_actor(String.t()) :: {:ok, String.t()} | {:error, :host_not_found}
|
||||||
|
defp domain_from_federated_actor(actor) do
|
||||||
|
case String.split(actor, "@") do
|
||||||
|
[_name, domain] ->
|
||||||
|
{:ok, domain}
|
||||||
|
|
||||||
|
_e ->
|
||||||
|
host = URI.parse(actor).host
|
||||||
|
if is_nil(host), do: {:error, :host_not_found}, else: {:ok, host}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec webfinger_from_json(map() | String.t()) ::
|
||||||
|
{:ok, map()} | {:error, :webfinger_information_not_json}
|
||||||
|
defp webfinger_from_json(doc) when is_map(doc) do
|
||||||
data =
|
data =
|
||||||
Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
|
Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
|
||||||
case {link["type"], link["rel"]} do
|
case {link["type"], link["rel"]} do
|
||||||
|
@ -97,31 +195,26 @@ defmodule Mobilizon.Federation.WebFinger do
|
||||||
{:ok, data}
|
{:ok, data}
|
||||||
end
|
end
|
||||||
|
|
||||||
def finger(actor) do
|
defp webfinger_from_json(_doc), do: {:error, :webfinger_information_not_json}
|
||||||
actor = String.trim_leading(actor, "@")
|
|
||||||
|
|
||||||
domain =
|
@spec find_link_from_template(String.t()) :: String.t() | {:error, :link_not_found}
|
||||||
case String.split(actor, "@") do
|
defp find_link_from_template(doc) do
|
||||||
[_name, domain] ->
|
with res when res in [nil, ""] <-
|
||||||
domain
|
xpath(doc, ~x"//Link[@rel=\"lrdd\"][@type=\"application/json\"]/@template"s),
|
||||||
|
res when res in [nil, ""] <- xpath(doc, ~x"//Link[@rel=\"lrdd\"]/@template"s),
|
||||||
|
do: {:error, :link_not_found}
|
||||||
|
end
|
||||||
|
|
||||||
_e ->
|
@spec fetch_document(String.t()) :: Tesla.Env.result()
|
||||||
URI.parse(actor).host
|
defp fetch_document(endpoint) do
|
||||||
end
|
with {:error, err} <- HostMetaClient.get(endpoint), do: {:error, err}
|
||||||
|
end
|
||||||
|
|
||||||
address = "http://#{domain}/.well-known/webfinger?resource=acct:#{actor}"
|
@spec address_invalid(String.t()) :: false | {:error, :invalid_address}
|
||||||
|
defp address_invalid(address) do
|
||||||
Logger.debug(inspect(address))
|
with %URI{host: host, scheme: scheme} <- URI.parse(address),
|
||||||
|
true <- is_nil(host) or is_nil(scheme) do
|
||||||
with false <- is_nil(domain),
|
{:error, :invalid_address}
|
||||||
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
|
||||||
WebfingerClient.get(address) do
|
|
||||||
webfinger_from_json(body)
|
|
||||||
else
|
|
||||||
e ->
|
|
||||||
Logger.debug(fn -> "Couldn't finger #{actor}" end)
|
|
||||||
Logger.debug(fn -> inspect(e) end)
|
|
||||||
{:error, e}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -321,7 +321,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||||
{:ok, _activity, follow} ->
|
{:ok, _activity, follow} ->
|
||||||
{:ok, follow}
|
{:ok, follow}
|
||||||
|
|
||||||
{:error, {:error, err}} when is_bitstring(err) ->
|
{:error, {:error, err}} when is_binary(err) ->
|
||||||
{:error, err}
|
{:error, err}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -336,7 +336,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||||
{:ok, _activity, follow} ->
|
{:ok, _activity, follow} ->
|
||||||
{:ok, follow}
|
{:ok, follow}
|
||||||
|
|
||||||
{:error, {:error, err}} when is_bitstring(err) ->
|
{:error, {:error, err}} when is_binary(err) ->
|
||||||
|
{:error, err}
|
||||||
|
|
||||||
|
{:error, err} when is_binary(err) ->
|
||||||
{:error, err}
|
{:error, err}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -351,7 +354,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||||
{:ok, _activity, follow} ->
|
{:ok, _activity, follow} ->
|
||||||
{:ok, follow}
|
{:ok, follow}
|
||||||
|
|
||||||
{:error, {:error, err}} when is_bitstring(err) ->
|
{:error, {:error, err}} when is_binary(err) ->
|
||||||
|
{:error, err}
|
||||||
|
|
||||||
|
{:error, err} when is_binary(err) ->
|
||||||
{:error, err}
|
{:error, err}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -134,6 +134,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
||||||
auth: %{
|
auth: %{
|
||||||
ldap: Config.ldap_enabled?(),
|
ldap: Config.ldap_enabled?(),
|
||||||
oauth_providers: Config.oauth_consumer_strategies()
|
oauth_providers: Config.oauth_consumer_strategies()
|
||||||
|
},
|
||||||
|
upload_limits: %{
|
||||||
|
default: Config.get([:instance, :upload_limit]),
|
||||||
|
avatar: Config.get([:instance, :avatar_upload_limit]),
|
||||||
|
banner: Config.get([:instance, :banner_upload_limit])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,7 +96,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||||
# TODO Move me to somewhere cleaner
|
# TODO Move me to somewhere cleaner
|
||||||
defp save_attached_pictures(args) do
|
defp save_attached_pictures(args) do
|
||||||
Enum.reduce([:avatar, :banner], args, fn key, args ->
|
Enum.reduce([:avatar, :banner], args, fn key, args ->
|
||||||
if Map.has_key?(args, key) && !is_nil(args[key][:media]) do
|
if is_map(args) && Map.has_key?(args, key) && !is_nil(args[key][:media]) do
|
||||||
pic = args[key][:media]
|
pic = args[key][:media]
|
||||||
|
|
||||||
with {:ok, %{name: name, url: url, content_type: content_type, size: _size}} <-
|
with {:ok, %{name: name, url: url, content_type: content_type, size: _size}} <-
|
||||||
|
@ -122,14 +122,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||||
}
|
}
|
||||||
) do
|
) do
|
||||||
with %Actor{id: creator_actor_id} = creator_actor <- Users.get_actor_for_user(user),
|
with %Actor{id: creator_actor_id} = creator_actor <- Users.get_actor_for_user(user),
|
||||||
args <- Map.update(args, :preferred_username, "", &String.downcase/1),
|
args when is_map(args) <- Map.update(args, :preferred_username, "", &String.downcase/1),
|
||||||
args <- Map.put(args, :creator_actor, creator_actor),
|
args when is_map(args) <- Map.put(args, :creator_actor, creator_actor),
|
||||||
args <- Map.put(args, :creator_actor_id, creator_actor_id),
|
args when is_map(args) <- Map.put(args, :creator_actor_id, creator_actor_id),
|
||||||
args <- save_attached_pictures(args),
|
{:picture, args} when is_map(args) <- {:picture, save_attached_pictures(args)},
|
||||||
{:ok, _activity, %Actor{type: :Group} = group} <-
|
{:ok, _activity, %Actor{type: :Group} = group} <-
|
||||||
API.Groups.create_group(args) do
|
API.Groups.create_group(args) do
|
||||||
{:ok, group}
|
{:ok, group}
|
||||||
else
|
else
|
||||||
|
{:picture, {:error, :file_too_large}} ->
|
||||||
|
{:error, dgettext("errors", "The provided picture is too heavy")}
|
||||||
|
|
||||||
{:error, err} when is_binary(err) ->
|
{:error, err} when is_binary(err) ->
|
||||||
{:error, err}
|
{:error, err}
|
||||||
end
|
end
|
||||||
|
@ -154,12 +157,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||||
with %Actor{} = updater_actor <- Users.get_actor_for_user(user),
|
with %Actor{} = updater_actor <- Users.get_actor_for_user(user),
|
||||||
{:administrator, true} <-
|
{:administrator, true} <-
|
||||||
{:administrator, Actors.is_administrator?(updater_actor.id, group_id)},
|
{:administrator, Actors.is_administrator?(updater_actor.id, group_id)},
|
||||||
args <- Map.put(args, :updater_actor, updater_actor),
|
args when is_map(args) <- Map.put(args, :updater_actor, updater_actor),
|
||||||
args <- save_attached_pictures(args),
|
{:picture, args} when is_map(args) <- {:picture, save_attached_pictures(args)},
|
||||||
{:ok, _activity, %Actor{type: :Group} = group} <-
|
{:ok, _activity, %Actor{type: :Group} = group} <-
|
||||||
API.Groups.update_group(args) do
|
API.Groups.update_group(args) do
|
||||||
{:ok, group}
|
{:ok, group}
|
||||||
else
|
else
|
||||||
|
{:picture, {:error, :file_too_large}} ->
|
||||||
|
{:error, dgettext("errors", "The provided picture is too heavy")}
|
||||||
|
|
||||||
{:error, err} when is_binary(err) ->
|
{:error, err} when is_binary(err) ->
|
||||||
{:error, err}
|
{:error, err}
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
|
||||||
@spec valid_email?(String.t() | nil) :: boolean
|
@spec valid_email?(String.t() | nil) :: boolean
|
||||||
defp valid_email?(email) when is_nil(email), do: false
|
defp valid_email?(email) when is_nil(email), do: false
|
||||||
|
|
||||||
defp valid_email?(email) when is_bitstring(email) do
|
defp valid_email?(email) when is_binary(email) do
|
||||||
email
|
email
|
||||||
|> String.trim()
|
|> String.trim()
|
||||||
|> Checker.valid?()
|
|> Checker.valid?()
|
||||||
|
|
|
@ -225,9 +225,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp save_picture(media, key) do
|
defp save_picture(media, key) do
|
||||||
with {:ok, %{name: name, url: url, content_type: content_type, size: _size}} <-
|
with {:ok, %{name: name, url: url, content_type: content_type, size: size}} <-
|
||||||
Upload.store(media.file, type: key, description: media.alt) do
|
Upload.store(media.file, type: key, description: media.alt) do
|
||||||
%{"name" => name, "url" => url, "mediaType" => content_type}
|
%{"name" => name, "url" => url, "content_type" => content_type, "size" => size}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
|
||||||
description: "The instance's enabled resource providers"
|
description: "The instance's enabled resource providers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
field(:upload_limits, :upload_limits, description: "The configuration for upload limits")
|
||||||
|
|
||||||
field(:timezones, list_of(:string), description: "The instance's available timezones")
|
field(:timezones, list_of(:string), description: "The instance's available timezones")
|
||||||
field(:features, :features, description: "The instance's features")
|
field(:features, :features, description: "The instance's features")
|
||||||
field(:version, :string, description: "The instance's version")
|
field(:version, :string, description: "The instance's version")
|
||||||
|
@ -283,6 +285,15 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
|
||||||
field(:label, :string, description: "The label for the auth provider")
|
field(:label, :string, description: "The label for the auth provider")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@desc """
|
||||||
|
An upload limits configuration
|
||||||
|
"""
|
||||||
|
object :upload_limits do
|
||||||
|
field(:default, :integer, description: "The default limitation, in bytes")
|
||||||
|
field(:avatar, :integer, description: "The avatar limitation, in bytes")
|
||||||
|
field(:banner, :integer, description: "The banner limitation, in bytes")
|
||||||
|
end
|
||||||
|
|
||||||
object :config_queries do
|
object :config_queries do
|
||||||
@desc "Get the instance config"
|
@desc "Get the instance config"
|
||||||
field :config, :config do
|
field :config, :config do
|
||||||
|
|
|
@ -16,9 +16,10 @@ defmodule Mix.Tasks.Mobilizon.Relay.Follow do
|
||||||
{:ok, _activity, _follow} ->
|
{:ok, _activity, _follow} ->
|
||||||
# put this task to sleep to allow the genserver to push out the messages
|
# put this task to sleep to allow the genserver to push out the messages
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
|
shell_info("Requested to follow #{target}")
|
||||||
|
|
||||||
{:error, e} ->
|
{:error, e} ->
|
||||||
IO.puts(:stderr, "Error while following #{target}: #{inspect(e)}")
|
shell_error("Error while following #{target}: #{inspect(e)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,10 @@ defmodule Mix.Tasks.Mobilizon.Relay.Unfollow do
|
||||||
{:ok, _activity, _follow} ->
|
{:ok, _activity, _follow} ->
|
||||||
# put this task to sleep to allow the genserver to push out the messages
|
# put this task to sleep to allow the genserver to push out the messages
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
|
shell_info("Unfollowed #{target}")
|
||||||
|
|
||||||
{:error, e} ->
|
{:error, e} ->
|
||||||
IO.puts(:stderr, "Error while unfollowing #{target}: #{inspect(e)}")
|
shell_error("Error while unfollowing #{target}: #{inspect(e)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ defmodule Mobilizon.Actors do
|
||||||
|
|
||||||
query
|
query
|
||||||
|> filter_by_type(type)
|
|> filter_by_type(type)
|
||||||
|> filter_by_name(String.split(name, "@"))
|
|> filter_by_name(name |> String.trim() |> String.trim_leading("@") |> String.split("@"))
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ defmodule Mobilizon.Admin do
|
||||||
defp stringify_struct(struct), do: struct
|
defp stringify_struct(struct), do: struct
|
||||||
|
|
||||||
def get_admin_setting_value(group, name, fallback \\ nil)
|
def get_admin_setting_value(group, name, fallback \\ nil)
|
||||||
when is_bitstring(group) and is_bitstring(name) do
|
when is_binary(group) and is_binary(name) do
|
||||||
case Repo.get_by(Setting, group: group, name: name) do
|
case Repo.get_by(Setting, group: group, name: name) do
|
||||||
nil ->
|
nil ->
|
||||||
fallback
|
fallback
|
||||||
|
|
|
@ -74,7 +74,7 @@ defmodule Mobilizon.Service.Geospatial.Provider do
|
||||||
%Geo.Point{coordinates: {x, y}, srid: srid}
|
%Geo.Point{coordinates: {x, y}, srid: srid}
|
||||||
end
|
end
|
||||||
|
|
||||||
def coordinates([x, y], srid) when is_bitstring(x) and is_bitstring(y) do
|
def coordinates([x, y], srid) when is_binary(x) and is_binary(y) do
|
||||||
%Geo.Point{coordinates: {String.to_float(x), String.to_float(y)}, srid: srid}
|
%Geo.Point{coordinates: {String.to_float(x), String.to_float(y)}, srid: srid}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,28 +5,26 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
|
||||||
|
|
||||||
alias Mobilizon.Config
|
alias Mobilizon.Config
|
||||||
|
|
||||||
@adapter Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
|
|
||||||
@default_opts [
|
@default_opts [
|
||||||
recv_timeout: 20_000
|
recv_timeout: 20_000
|
||||||
]
|
]
|
||||||
@user_agent Config.instance_user_agent()
|
|
||||||
|
|
||||||
def client(options \\ []) do
|
def client(options \\ []) do
|
||||||
headers = Keyword.get(options, :headers, [])
|
headers = Keyword.get(options, :headers, [])
|
||||||
|
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
|
||||||
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
|
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
|
||||||
|
|
||||||
middleware = [
|
middleware = [
|
||||||
{Tesla.Middleware.Headers,
|
{Tesla.Middleware.Headers,
|
||||||
[{"User-Agent", @user_agent}, {"Accept", "application/activity+json"}] ++ headers},
|
[{"User-Agent", Config.instance_user_agent()}, {"Accept", "application/activity+json"}] ++
|
||||||
|
headers},
|
||||||
Tesla.Middleware.FollowRedirects,
|
Tesla.Middleware.FollowRedirects,
|
||||||
{Tesla.Middleware.Timeout, timeout: 10_000},
|
{Tesla.Middleware.Timeout, timeout: 10_000},
|
||||||
{Tesla.Middleware.JSON,
|
{Tesla.Middleware.JSON,
|
||||||
decode_content_types: ["application/activity+json", "application/ld+json"]}
|
decode_content_types: ["application/activity+json", "application/ld+json"]}
|
||||||
]
|
]
|
||||||
|
|
||||||
adapter = {@adapter, opts}
|
Tesla.client(middleware, {adapter, opts})
|
||||||
|
|
||||||
Tesla.client(middleware, adapter)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(client, url) do
|
def get(client, url) do
|
||||||
|
|
|
@ -13,13 +13,11 @@ defmodule Mobilizon.Service.HTTP.GeospatialClient do
|
||||||
|
|
||||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||||
|
|
||||||
@user_agent Config.instance_user_agent()
|
|
||||||
|
|
||||||
plug(Tesla.Middleware.FollowRedirects)
|
plug(Tesla.Middleware.FollowRedirects)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Headers, [{"User-Agent", @user_agent}])
|
plug(Tesla.Middleware.Headers, [{"User-Agent", Config.instance_user_agent()}])
|
||||||
|
|
||||||
plug(Tesla.Middleware.JSON)
|
plug(Tesla.Middleware.JSON)
|
||||||
end
|
end
|
||||||
|
|
24
lib/service/http/host_meta_client.ex
Normal file
24
lib/service/http/host_meta_client.ex
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
defmodule Mobilizon.Service.HTTP.HostMetaClient do
|
||||||
|
@moduledoc """
|
||||||
|
Tesla HTTP Basic Client
|
||||||
|
with XML middleware
|
||||||
|
"""
|
||||||
|
|
||||||
|
use Tesla
|
||||||
|
alias Mobilizon.Config
|
||||||
|
|
||||||
|
@default_opts [
|
||||||
|
recv_timeout: 20_000
|
||||||
|
]
|
||||||
|
|
||||||
|
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||||
|
|
||||||
|
plug(Tesla.Middleware.FollowRedirects)
|
||||||
|
|
||||||
|
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
||||||
|
|
||||||
|
plug(Tesla.Middleware.Headers, [
|
||||||
|
{"User-Agent", Config.instance_user_agent()},
|
||||||
|
{"Accept", "application/xrd+xml, application/xml, text/xml"}
|
||||||
|
])
|
||||||
|
end
|
|
@ -12,11 +12,9 @@ defmodule Mobilizon.Service.HTTP.RemoteMediaDownloaderClient do
|
||||||
|
|
||||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||||
|
|
||||||
@user_agent Config.instance_user_agent()
|
|
||||||
|
|
||||||
plug(Tesla.Middleware.FollowRedirects)
|
plug(Tesla.Middleware.FollowRedirects)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Headers, [{"User-Agent", @user_agent}])
|
plug(Tesla.Middleware.Headers, [{"User-Agent", Config.instance_user_agent()}])
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,11 +12,9 @@ defmodule Mobilizon.Service.HTTP.RichMediaPreviewClient do
|
||||||
|
|
||||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||||
|
|
||||||
@user_agent Config.instance_user_agent()
|
|
||||||
|
|
||||||
plug(Tesla.Middleware.FollowRedirects)
|
plug(Tesla.Middleware.FollowRedirects)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Headers, [{"User-Agent", @user_agent}])
|
plug(Tesla.Middleware.Headers, [{"User-Agent", Config.instance_user_agent()}])
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,14 +13,12 @@ defmodule Mobilizon.Service.HTTP.WebfingerClient do
|
||||||
|
|
||||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||||
|
|
||||||
@user_agent Config.instance_user_agent()
|
|
||||||
|
|
||||||
plug(Tesla.Middleware.FollowRedirects)
|
plug(Tesla.Middleware.FollowRedirects)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
plug(Tesla.Middleware.Timeout, timeout: 10_000)
|
||||||
|
|
||||||
plug(Tesla.Middleware.Headers, [
|
plug(Tesla.Middleware.Headers, [
|
||||||
{"User-Agent", @user_agent},
|
{"User-Agent", Config.instance_user_agent()},
|
||||||
{"Accept", "application/json, application/activity+json, application/jrd+json"}
|
{"Accept", "application/json, application/activity+json, application/jrd+json"}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,12 @@ defmodule Mobilizon.Web.Endpoint do
|
||||||
plug(Plug.RequestId)
|
plug(Plug.RequestId)
|
||||||
plug(Plug.Logger)
|
plug(Plug.Logger)
|
||||||
|
|
||||||
|
upload_limit =
|
||||||
|
Keyword.get(Application.get_env(:mobilizon, :instance, []), :upload_limit, 10_485_760)
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
Plug.Parsers,
|
Plug.Parsers,
|
||||||
parsers: [:urlencoded, {:multipart, length: 10_000_000}, :json, Absinthe.Plug.Parser],
|
parsers: [:urlencoded, {:multipart, length: upload_limit}, :json, Absinthe.Plug.Parser],
|
||||||
pass: ["*/*"],
|
pass: ["*/*"],
|
||||||
json_decoder: Jason
|
json_decoder: Jason
|
||||||
)
|
)
|
||||||
|
|
4
lib/web/plugs/not_acceptable_error.ex
Normal file
4
lib/web/plugs/not_acceptable_error.ex
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defimpl Plug.Exception, for: Phoenix.NotAcceptableError do
|
||||||
|
def status(_exception), do: 406
|
||||||
|
def actions(_exception), do: []
|
||||||
|
end
|
1
mix.exs
1
mix.exs
|
@ -144,6 +144,7 @@ defmodule Mobilizon.Mixfile do
|
||||||
{:slugger, "~> 0.3"},
|
{:slugger, "~> 0.3"},
|
||||||
{:sentry, "~> 8.0"},
|
{:sentry, "~> 8.0"},
|
||||||
{:html_entities, "~> 0.5"},
|
{:html_entities, "~> 0.5"},
|
||||||
|
{:sweet_xml, "~> 0.6.6"},
|
||||||
# Dev and test dependencies
|
# Dev and test dependencies
|
||||||
{:phoenix_live_reload, "~> 1.2", only: [:dev, :e2e]},
|
{:phoenix_live_reload, "~> 1.2", only: [:dev, :e2e]},
|
||||||
{:ex_machina, "~> 2.3", only: [:dev, :test]},
|
{:ex_machina, "~> 2.3", only: [:dev, :test]},
|
||||||
|
|
2
mix.lock
2
mix.lock
|
@ -33,6 +33,7 @@
|
||||||
"elixir_feed_parser": {:hex, :elixir_feed_parser, "2.1.0", "bb96fb6422158dc7ad59de62ef211cc69d264acbbe63941a64a5dce97bbbc2e6", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2d3c62fe7b396ee3b73d7160bc8fadbd78bfe9597c98c7d79b3f1038d9cba28f"},
|
"elixir_feed_parser": {:hex, :elixir_feed_parser, "2.1.0", "bb96fb6422158dc7ad59de62ef211cc69d264acbbe63941a64a5dce97bbbc2e6", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2d3c62fe7b396ee3b73d7160bc8fadbd78bfe9597c98c7d79b3f1038d9cba28f"},
|
||||||
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
|
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
|
||||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||||
|
"erlsom": {:hex, :erlsom, "1.5.0", "c5a5cdd0ee0e8dca62bcc4b13ff08da24fdefc16ccd8b25282a2fda2ba1be24a", [:rebar3], [], "hexpm", "55a9dbf9cfa77fcfc108bd8e2c4f9f784dea228a8f4b06ea10b684944946955a"},
|
||||||
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
|
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
|
||||||
"ex_cldr": {:hex, :ex_cldr, "2.20.0", "571a4b490c333809be59cc984a21be2deaab1db9e2418e323d5935aec8b1394a", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.15", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "06147e4a27be62e6fe92db14cf5048c645927bfc530aa1cc6af8c92d65e32427"},
|
"ex_cldr": {:hex, :ex_cldr, "2.20.0", "571a4b490c333809be59cc984a21be2deaab1db9e2418e323d5935aec8b1394a", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.15", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "06147e4a27be62e6fe92db14cf5048c645927bfc530aa1cc6af8c92d65e32427"},
|
||||||
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.13.0", "6bea6f3c54d74c0ed131dd17e1cff68e02b7053f24c2fac91f129e5221ff723a", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.17", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.5", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d07ab6b2164b6a0861de6ecb600747aab61c94a0b9c001e36c2e0b731eeb567a"},
|
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.13.0", "6bea6f3c54d74c0ed131dd17e1cff68e02b7053f24c2fac91f129e5221ff723a", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.17", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.5", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d07ab6b2164b6a0861de6ecb600747aab61c94a0b9c001e36c2e0b731eeb567a"},
|
||||||
|
@ -122,6 +123,7 @@
|
||||||
"slugger": {:hex, :slugger, "0.3.0", "efc667ab99eee19a48913ccf3d038b1fb9f165fa4fbf093be898b8099e61b6ed", [:mix], [], "hexpm", "20d0ded0e712605d1eae6c5b4889581c3460d92623a930ddda91e0e609b5afba"},
|
"slugger": {:hex, :slugger, "0.3.0", "efc667ab99eee19a48913ccf3d038b1fb9f165fa4fbf093be898b8099e61b6ed", [:mix], [], "hexpm", "20d0ded0e712605d1eae6c5b4889581c3460d92623a930ddda91e0e609b5afba"},
|
||||||
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
|
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
|
||||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||||
|
"sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"},
|
||||||
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
|
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
|
||||||
"tesla": {:hex, :tesla, "1.4.1", "ff855f1cac121e0d16281b49e8f066c4a0d89965f98864515713878cca849ac8", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "95f5de35922c8c4b3945bee7406f66eb680b0955232f78f5fb7e853aa1ce201a"},
|
"tesla": {:hex, :tesla, "1.4.1", "ff855f1cac121e0d16281b49e8f066c4a0d89965f98864515713878cca849ac8", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "95f5de35922c8c4b3945bee7406f66eb680b0955232f78f5fb7e853aa1ce201a"},
|
||||||
"timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"},
|
"timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"},
|
||||||
|
|
|
@ -54,10 +54,7 @@ defmodule Mobilizon.Federation.WebFingerTest do
|
||||||
describe "fingering" do
|
describe "fingering" do
|
||||||
test "a mastodon actor" do
|
test "a mastodon actor" do
|
||||||
use_cassette "webfinger/mastodon" do
|
use_cassette "webfinger/mastodon" do
|
||||||
res = %{
|
res = "https://social.tcit.fr/users/#{@mastodon_account_username}"
|
||||||
"subject" => "acct:" <> @mastodon_account,
|
|
||||||
"url" => "https://social.tcit.fr/users/#{@mastodon_account_username}"
|
|
||||||
}
|
|
||||||
|
|
||||||
assert {:ok, res} == WebFinger.finger(@mastodon_account)
|
assert {:ok, res} == WebFinger.finger(@mastodon_account)
|
||||||
end
|
end
|
||||||
|
@ -65,10 +62,7 @@ defmodule Mobilizon.Federation.WebFingerTest do
|
||||||
|
|
||||||
test "a pleroma actor" do
|
test "a pleroma actor" do
|
||||||
use_cassette "webfinger/pleroma" do
|
use_cassette "webfinger/pleroma" do
|
||||||
res = %{
|
res = "https://pleroma.soykaf.com/users/#{@pleroma_account_username}"
|
||||||
"subject" => "acct:" <> @pleroma_account,
|
|
||||||
"url" => "https://pleroma.soykaf.com/users/#{@pleroma_account_username}"
|
|
||||||
}
|
|
||||||
|
|
||||||
assert {:ok, res} == WebFinger.finger(@pleroma_account)
|
assert {:ok, res} == WebFinger.finger(@pleroma_account)
|
||||||
end
|
end
|
||||||
|
@ -76,10 +70,7 @@ defmodule Mobilizon.Federation.WebFingerTest do
|
||||||
|
|
||||||
test "a peertube actor" do
|
test "a peertube actor" do
|
||||||
use_cassette "webfinger/peertube" do
|
use_cassette "webfinger/peertube" do
|
||||||
res = %{
|
res = "https://framatube.org/accounts/#{@peertube_account_username}"
|
||||||
"subject" => "acct:" <> @peertube_account,
|
|
||||||
"url" => "https://framatube.org/accounts/#{@peertube_account_username}"
|
|
||||||
}
|
|
||||||
|
|
||||||
assert {:ok, res} == WebFinger.finger(@peertube_account)
|
assert {:ok, res} == WebFinger.finger(@peertube_account)
|
||||||
end
|
end
|
||||||
|
@ -87,10 +78,7 @@ defmodule Mobilizon.Federation.WebFingerTest do
|
||||||
|
|
||||||
test "a friendica actor" do
|
test "a friendica actor" do
|
||||||
use_cassette "webfinger/friendica" do
|
use_cassette "webfinger/friendica" do
|
||||||
res = %{
|
res = "https://squeet.me/profile/#{@friendica_account_username}"
|
||||||
"subject" => "acct:" <> @friendica_account,
|
|
||||||
"url" => "https://squeet.me/profile/#{@friendica_account_username}"
|
|
||||||
}
|
|
||||||
|
|
||||||
assert {:ok, res} == WebFinger.finger(@friendica_account)
|
assert {:ok, res} == WebFinger.finger(@friendica_account)
|
||||||
end
|
end
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,101 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"request": {
|
|
||||||
"body": "",
|
|
||||||
"headers": {
|
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
|
||||||
},
|
|
||||||
"method": "get",
|
|
||||||
"options": {
|
|
||||||
"follow_redirect": "true"
|
|
||||||
},
|
|
||||||
"request_body": "",
|
|
||||||
"url": "http://mobilizon1.com/.well-known/webfinger?resource=acct:relay@mobilizon1.com"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"binary": false,
|
|
||||||
"body": "{\"aliases\":[\"http://mobilizon1.com/relay\"],\"links\":[{\"href\":\"http://mobilizon1.com/relay\",\"rel\":\"self\",\"type\":\"application/activity+json\"},{\"href\":\"http://mobilizon1.com/relay\",\"rel\":\"https://webfinger.net/rel/profile-page/\",\"type\":\"text/html\"}],\"subject\":\"acct:relay@mobilizon1.com\"}",
|
|
||||||
"headers": {
|
|
||||||
"Server": "nginx/1.16.1",
|
|
||||||
"Date": "Fri, 13 Dec 2019 09:41:40 GMT",
|
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
|
||||||
"Content-Length": "284",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"access-control-allow-credentials": "true",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "Fd_k7OtPJ28p8-MAAAOh"
|
|
||||||
},
|
|
||||||
"status_code": 200,
|
|
||||||
"type": "ok"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"request": {
|
|
||||||
"body": "",
|
|
||||||
"headers": {
|
|
||||||
"Accept": "application/activity+json"
|
|
||||||
},
|
|
||||||
"method": "get",
|
|
||||||
"options": {
|
|
||||||
"follow_redirect": "true"
|
|
||||||
},
|
|
||||||
"request_body": "",
|
|
||||||
"url": "http://mobilizon1.com/relay"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"binary": false,
|
|
||||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://litepub.social/litepub/context.jsonld\",{\"Hashtag\":\"as:Hashtag\",\"category\":\"sc:category\",\"ical\":\"http://www.w3.org/2002/12/cal/ical#\",\"joinMode\":{\"@id\":\"mz:joinMode\",\"@type\":\"mz:joinModeType\"},\"joinModeType\":{\"@id\":\"mz:joinModeType\",\"@type\":\"rdfs:Class\"},\"maximumAttendeeCapacity\":\"sc:maximumAttendeeCapacity\",\"mz\":\"https://joinmobilizon.org/ns#\",\"repliesModerationOption\":{\"@id\":\"mz:repliesModerationOption\",\"@type\":\"mz:repliesModerationOptionType\"},\"repliesModerationOptionType\":{\"@id\":\"mz:repliesModerationOptionType\",\"@type\":\"rdfs:Class\"},\"sc\":\"http://schema.org#\",\"uuid\":\"sc:identifier\"}],\"endpoints\":{\"sharedInbox\":\"http://mobilizon1.com/inbox\"},\"followers\":\"http://mobilizon1.com/relay/followers\",\"following\":\"http://mobilizon1.com/relay/following\",\"id\":\"http://mobilizon1.com/relay\",\"inbox\":\"http://mobilizon1.com/inbox\",\"manuallyApprovesFollowers\":false,\"name\":\"Mobilizon\",\"outbox\":null,\"preferredUsername\":\"relay\",\"publicKey\":{\"id\":\"http://mobilizon1.com/relay#main-key\",\"owner\":\"http://mobilizon1.com/relay\",\"publicKeyPem\":\"-----BEGIN RSA PUBLIC KEY-----\\nMIIBCgKCAQEAqBbeHMV5UVw0AIVch7fWDp2it5rqbGZX6yXPYnnT8LHhdvfv3DFk\\npk74BN66MzNqsthvSVznu2BEil0sEKD5rQoE9Yirhzz/LN9SlnU+u6262nBA18E3\\nkQ10RgL2jpZ9e8Om6qYqarhN7draupJXYRKEaUoEFPT09ABbwQv+4K1YadU8klJi\\nHJ6D+IIHiXNizfsxVLDKpbUKStMYeEzyfqCkWw0EQEuzc3O7Aci5lwCMkCts2993\\nsTbNyzsYAVWJNcy/An1F1P+K4iZhWEtZInQz67MBtjMWtQUhyWib0e671HdBiWM6\\nkZq74U8c6RR6eMzBLuY7YAUCG6nWg90zxwIDAQAB\\n-----END RSA PUBLIC KEY-----\\n\\n\"},\"summary\":\"Change this to a proper description of your instance\",\"type\":\"Application\",\"url\":\"http://mobilizon1.com/relay\"}",
|
|
||||||
"headers": {
|
|
||||||
"Server": "nginx/1.16.1",
|
|
||||||
"Date": "Fri, 13 Dec 2019 09:41:41 GMT",
|
|
||||||
"Content-Type": "application/activity+json",
|
|
||||||
"Content-Length": "1657",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"access-control-allow-credentials": "true",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "Fd_k7PjOAWuySL0AAAPB"
|
|
||||||
},
|
|
||||||
"status_code": 200,
|
|
||||||
"type": "ok"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"request": {
|
|
||||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://litepub.social/litepub/context.jsonld\",{\"Hashtag\":\"as:Hashtag\",\"category\":\"sc:category\",\"ical\":\"http://www.w3.org/2002/12/cal/ical#\",\"joinMode\":{\"@id\":\"mz:joinMode\",\"@type\":\"mz:joinModeType\"},\"joinModeType\":{\"@id\":\"mz:joinModeType\",\"@type\":\"rdfs:Class\"},\"maximumAttendeeCapacity\":\"sc:maximumAttendeeCapacity\",\"mz\":\"https://joinmobilizon.org/ns#\",\"repliesModerationOption\":{\"@id\":\"mz:repliesModerationOption\",\"@type\":\"mz:repliesModerationOptionType\"},\"repliesModerationOptionType\":{\"@id\":\"mz:repliesModerationOptionType\",\"@type\":\"rdfs:Class\"},\"sc\":\"http://schema.org#\",\"uuid\":\"sc:identifier\"}],\"actor\":\"http://mobilizon.test/relay\",\"cc\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"id\":\"http://mobilizon.test/follow/b7791977-2a75-4715-815b-6e7125065b71\",\"object\":\"http://mobilizon1.com/relay\",\"to\":[\"http://mobilizon1.com/relay\"],\"type\":\"Follow\"}",
|
|
||||||
"headers": {
|
|
||||||
"Content-Type": "application/activity+json",
|
|
||||||
"signature": "keyId=\"http://mobilizon.test/relay#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-length date digest host\",signature=\"WbyGHT/WdvdRpWek8uCGHrFSblLpg+Iq802R5S2cjNj035OKpxRmu1r8u9Qr5KGIKgZn6LHt9YmB+PNlwsubPtTSkJpE8AAUDMHLKgCrH7A5Q6x6GlARl5bHNo4QtOxkXvnEbn31xfNDNp70QqZb/emw95TnELYUlMLZds0qYutT8U4WdDhSWcVytQmKJWNZXxEj+KlMDUaxag3lGscJ/HY0F+yGNov7FHthid1Y4LTGFsp/tismnMTlba12NH/kXPHtduNsX8uxFslM2ODwqAaospTGEpXmr9CPgbNy7626qgYaR2RdB/fYlCayLI4JJIlH8gOdocGHPrWNtVEHaQ==\"",
|
|
||||||
"digest": "SHA-256=ibNFcsnBeCCjWZo9We60tKfbRN3el0WCMVdOxtuC1cg=",
|
|
||||||
"date": "Fri, 13 Dec 2019 09:41:41 GMT"
|
|
||||||
},
|
|
||||||
"method": "post",
|
|
||||||
"options": {
|
|
||||||
"pool": "default"
|
|
||||||
},
|
|
||||||
"request_body": "",
|
|
||||||
"url": "http://mobilizon1.com/inbox"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"binary": false,
|
|
||||||
"body": "# HTTPoison.Error at POST /inbox\n\nException:\n\n ** (HTTPoison.Error) :nxdomain\n (httpoison) lib/httpoison.ex:128: HTTPoison.request!/5\n (mobilizon) lib/service/activity_pub/activity_pub.ex:610: Mobilizon.Service.ActivityPub.fetch_and_prepare_actor_from_url/1\n (mobilizon) lib/service/activity_pub/activity_pub.ex:473: Mobilizon.Service.ActivityPub.make_actor_from_url/2\n (mobilizon) lib/service/activity_pub/activity_pub.ex:122: Mobilizon.Service.ActivityPub.get_or_fetch_actor_by_url/2\n (mobilizon) lib/service/http_signatures/signature.ex:54: Mobilizon.Federation.HTTPSignatures.Signature.get_public_key_for_url/1\n (mobilizon) lib/service/http_signatures/signature.ex:74: Mobilizon.Federation.HTTPSignatures.Signature.fetch_public_key/1\n (http_signatures) lib/http_signatures/http_signatures.ex:40: HTTPSignatures.validate_conn/1\n (mobilizon) lib/mobilizon_web/http_signature.ex:45: Mobilizon.Web.HTTPSignaturePlug.call/2\n (mobilizon) Mobilizon.Web.Router.activity_pub_signature/2\n (mobilizon) lib/mobilizon_web/router.ex:1: Mobilizon.Web.Router.__pipe_through7__/1\n (phoenix) lib/phoenix/router.ex:283: Phoenix.Router.__call__/2\n (mobilizon) lib/mobilizon_web/endpoint.ex:1: Mobilizon.Web.Endpoint.plug_builder_call/2\n (mobilizon) lib/plug/debugger.ex:122: Mobilizon.Web.Endpoint.\"call (overridable 3)\"/2\n (mobilizon) lib/mobilizon_web/endpoint.ex:1: Mobilizon.Web.Endpoint.call/2\n (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:42: Phoenix.Endpoint.Cowboy2Handler.init/4\n (cowboy) /home/tcit/dev/frama/mobilizon/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2\n (cowboy) /home/tcit/dev/frama/mobilizon/deps/cowboy/src/cowboy_stream_h.erl:320: :cowboy_stream_h.execute/3\n (cowboy) /home/tcit/dev/frama/mobilizon/deps/cowboy/src/cowboy_stream_h.erl:302: :cowboy_stream_h.request_process/3\n (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3\n \n\n## Connection details\n\n### Params\n\n %{\"@context\" => [\"https://www.w3.org/ns/activitystreams\", \"https://litepub.social/litepub/context.jsonld\", %{\"Hashtag\" => \"as:Hashtag\", \"category\" => \"sc:category\", \"ical\" => \"http://www.w3.org/2002/12/cal/ical#\", \"joinMode\" => %{\"@id\" => \"mz:joinMode\", \"@type\" => \"mz:joinModeType\"}, \"joinModeType\" => %{\"@id\" => \"mz:joinModeType\", \"@type\" => \"rdfs:Class\"}, \"maximumAttendeeCapacity\" => \"sc:maximumAttendeeCapacity\", \"mz\" => \"https://joinmobilizon.org/ns#\", \"repliesModerationOption\" => %{\"@id\" => \"mz:repliesModerationOption\", \"@type\" => \"mz:repliesModerationOptionType\"}, \"repliesModerationOptionType\" => %{\"@id\" => \"mz:repliesModerationOptionType\", \"@type\" => \"rdfs:Class\"}, \"sc\" => \"http://schema.org#\", \"uuid\" => \"sc:identifier\"}], \"actor\" => \"http://mobilizon.test/relay\", \"cc\" => [\"https://www.w3.org/ns/activitystreams#Public\"], \"id\" => \"http://mobilizon.test/follow/b7791977-2a75-4715-815b-6e7125065b71\", \"object\" => \"http://mobilizon1.com/relay\", \"to\" => [\"http://mobilizon1.com/relay\"], \"type\" => \"Follow\"}\n\n### Request info\n\n * URI: http://mobilizon1.com:80/inbox\n * Query string: \n\n### Headers\n \n * connection: upgrade\n * content-length: 912\n * content-type: application/activity+json\n * date: Fri, 13 Dec 2019 09:41:41 GMT\n * digest: SHA-256=ibNFcsnBeCCjWZo9We60tKfbRN3el0WCMVdOxtuC1cg=\n * host: mobilizon1.com\n * signature: keyId=\"http://mobilizon.test/relay#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-length date digest host\",signature=\"WbyGHT/WdvdRpWek8uCGHrFSblLpg+Iq802R5S2cjNj035OKpxRmu1r8u9Qr5KGIKgZn6LHt9YmB+PNlwsubPtTSkJpE8AAUDMHLKgCrH7A5Q6x6GlARl5bHNo4QtOxkXvnEbn31xfNDNp70QqZb/emw95TnELYUlMLZds0qYutT8U4WdDhSWcVytQmKJWNZXxEj+KlMDUaxag3lGscJ/HY0F+yGNov7FHthid1Y4LTGFsp/tismnMTlba12NH/kXPHtduNsX8uxFslM2ODwqAaospTGEpXmr9CPgbNy7626qgYaR2RdB/fYlCayLI4JJIlH8gOdocGHPrWNtVEHaQ==\"\n * user-agent: hackney/1.15.2\n * x-forwarded-for: 127.0.0.1\n * x-real-ip: 127.0.0.1\n\n### Session\n\n %{}\n",
|
|
||||||
"headers": {
|
|
||||||
"Server": "nginx/1.16.1",
|
|
||||||
"Date": "Fri, 13 Dec 2019 09:41:41 GMT",
|
|
||||||
"Content-Type": "text/markdown; charset=utf-8",
|
|
||||||
"Content-Length": "3977",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"access-control-allow-credentials": "true",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "Fd_k7PoZpCCBYRQAAAPh"
|
|
||||||
},
|
|
||||||
"status_code": 500,
|
|
||||||
"type": "ok"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,101 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"request": {
|
|
||||||
"body": "",
|
|
||||||
"headers": {
|
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
|
||||||
},
|
|
||||||
"method": "get",
|
|
||||||
"options": {
|
|
||||||
"follow_redirect": "true"
|
|
||||||
},
|
|
||||||
"request_body": "",
|
|
||||||
"url": "http://mobilizon1.com/.well-known/webfinger?resource=acct:relay@mobilizon1.com"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"binary": false,
|
|
||||||
"body": "{\"aliases\":[\"http://mobilizon1.com/relay\"],\"links\":[{\"href\":\"http://mobilizon1.com/relay\",\"rel\":\"self\",\"type\":\"application/activity+json\"},{\"href\":\"http://mobilizon1.com/relay\",\"rel\":\"https://webfinger.net/rel/profile-page/\",\"type\":\"text/html\"}],\"subject\":\"acct:relay@mobilizon1.com\"}",
|
|
||||||
"headers": {
|
|
||||||
"Server": "nginx/1.16.1",
|
|
||||||
"Date": "Fri, 13 Dec 2019 09:41:39 GMT",
|
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
|
||||||
"Content-Length": "284",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"access-control-allow-credentials": "true",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "Fd_k7LmY5k0CMQkAAANB"
|
|
||||||
},
|
|
||||||
"status_code": 200,
|
|
||||||
"type": "ok"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"request": {
|
|
||||||
"body": "",
|
|
||||||
"headers": {
|
|
||||||
"Accept": "application/activity+json"
|
|
||||||
},
|
|
||||||
"method": "get",
|
|
||||||
"options": {
|
|
||||||
"follow_redirect": "true"
|
|
||||||
},
|
|
||||||
"request_body": "",
|
|
||||||
"url": "http://mobilizon1.com/relay"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"binary": false,
|
|
||||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://litepub.social/litepub/context.jsonld\",{\"Hashtag\":\"as:Hashtag\",\"category\":\"sc:category\",\"ical\":\"http://www.w3.org/2002/12/cal/ical#\",\"joinMode\":{\"@id\":\"mz:joinMode\",\"@type\":\"mz:joinModeType\"},\"joinModeType\":{\"@id\":\"mz:joinModeType\",\"@type\":\"rdfs:Class\"},\"maximumAttendeeCapacity\":\"sc:maximumAttendeeCapacity\",\"mz\":\"https://joinmobilizon.org/ns#\",\"repliesModerationOption\":{\"@id\":\"mz:repliesModerationOption\",\"@type\":\"mz:repliesModerationOptionType\"},\"repliesModerationOptionType\":{\"@id\":\"mz:repliesModerationOptionType\",\"@type\":\"rdfs:Class\"},\"sc\":\"http://schema.org#\",\"uuid\":\"sc:identifier\"}],\"endpoints\":{\"sharedInbox\":\"http://mobilizon1.com/inbox\"},\"followers\":\"http://mobilizon1.com/relay/followers\",\"following\":\"http://mobilizon1.com/relay/following\",\"id\":\"http://mobilizon1.com/relay\",\"inbox\":\"http://mobilizon1.com/inbox\",\"manuallyApprovesFollowers\":false,\"name\":\"Mobilizon\",\"outbox\":null,\"preferredUsername\":\"relay\",\"publicKey\":{\"id\":\"http://mobilizon1.com/relay#main-key\",\"owner\":\"http://mobilizon1.com/relay\",\"publicKeyPem\":\"-----BEGIN RSA PUBLIC KEY-----\\nMIIBCgKCAQEAqBbeHMV5UVw0AIVch7fWDp2it5rqbGZX6yXPYnnT8LHhdvfv3DFk\\npk74BN66MzNqsthvSVznu2BEil0sEKD5rQoE9Yirhzz/LN9SlnU+u6262nBA18E3\\nkQ10RgL2jpZ9e8Om6qYqarhN7draupJXYRKEaUoEFPT09ABbwQv+4K1YadU8klJi\\nHJ6D+IIHiXNizfsxVLDKpbUKStMYeEzyfqCkWw0EQEuzc3O7Aci5lwCMkCts2993\\nsTbNyzsYAVWJNcy/An1F1P+K4iZhWEtZInQz67MBtjMWtQUhyWib0e671HdBiWM6\\nkZq74U8c6RR6eMzBLuY7YAUCG6nWg90zxwIDAQAB\\n-----END RSA PUBLIC KEY-----\\n\\n\"},\"summary\":\"Change this to a proper description of your instance\",\"type\":\"Application\",\"url\":\"http://mobilizon1.com/relay\"}",
|
|
||||||
"headers": {
|
|
||||||
"Server": "nginx/1.16.1",
|
|
||||||
"Date": "Fri, 13 Dec 2019 09:41:40 GMT",
|
|
||||||
"Content-Type": "application/activity+json",
|
|
||||||
"Content-Length": "1657",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"access-control-allow-credentials": "true",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "Fd_k7L4h92fDp5cAAANh"
|
|
||||||
},
|
|
||||||
"status_code": 200,
|
|
||||||
"type": "ok"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"request": {
|
|
||||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://litepub.social/litepub/context.jsonld\",{\"Hashtag\":\"as:Hashtag\",\"category\":\"sc:category\",\"ical\":\"http://www.w3.org/2002/12/cal/ical#\",\"joinMode\":{\"@id\":\"mz:joinMode\",\"@type\":\"mz:joinModeType\"},\"joinModeType\":{\"@id\":\"mz:joinModeType\",\"@type\":\"rdfs:Class\"},\"maximumAttendeeCapacity\":\"sc:maximumAttendeeCapacity\",\"mz\":\"https://joinmobilizon.org/ns#\",\"repliesModerationOption\":{\"@id\":\"mz:repliesModerationOption\",\"@type\":\"mz:repliesModerationOptionType\"},\"repliesModerationOptionType\":{\"@id\":\"mz:repliesModerationOptionType\",\"@type\":\"rdfs:Class\"},\"sc\":\"http://schema.org#\",\"uuid\":\"sc:identifier\"}],\"actor\":\"http://mobilizon.test/relay\",\"cc\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"id\":\"http://mobilizon.test/follow/57a6973e-f43f-4533-bf71-7a14a4c6e5ac\",\"object\":\"http://mobilizon1.com/relay\",\"to\":[\"http://mobilizon1.com/relay\"],\"type\":\"Follow\"}",
|
|
||||||
"headers": {
|
|
||||||
"Content-Type": "application/activity+json",
|
|
||||||
"signature": "keyId=\"http://mobilizon.test/relay#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-length date digest host\",signature=\"JQPqSiJ0ZYdU6llrYXNMuN/bfzoLyubwOB59bljFq6i8ORXLw62Pt7Jue5WkMsySFcCXgS8k8K/H81YZkKzfWadwQV9L5rQEFSuW/DYJ2xffsDj90GsSi+sDRaQ5Ke8nPEbEMGR9jalh/F2VL97XscCgm6i3tdpbs6aFmqjKC+LzeH665t0WCHUxTgK47wECrMHw3j7lteGdm6N6IKWoWsRYeJoyFr/QCbNdWQOaAYYpCbJd0fjhPQRHhWQXidBoaDkhwesWc3mO8pvEnply9ES7Nzc6ULK7B98hg+aWeep8/KzRbxFyJ0OgnDJj/l39QiJ9t7v0yHX/WUzn0CaiiQ==\"",
|
|
||||||
"digest": "SHA-256=Qc9d9X3qh2EqIqtn/72iY17OMDXAOINDC10hARNAc4w=",
|
|
||||||
"date": "Fri, 13 Dec 2019 09:41:40 GMT"
|
|
||||||
},
|
|
||||||
"method": "post",
|
|
||||||
"options": {
|
|
||||||
"pool": "default"
|
|
||||||
},
|
|
||||||
"request_body": "",
|
|
||||||
"url": "http://mobilizon1.com/inbox"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"binary": false,
|
|
||||||
"body": "# HTTPoison.Error at POST /inbox\n\nException:\n\n ** (HTTPoison.Error) :nxdomain\n (httpoison) lib/httpoison.ex:128: HTTPoison.request!/5\n (mobilizon) lib/service/activity_pub/activity_pub.ex:610: Mobilizon.Service.ActivityPub.fetch_and_prepare_actor_from_url/1\n (mobilizon) lib/service/activity_pub/activity_pub.ex:473: Mobilizon.Service.ActivityPub.make_actor_from_url/2\n (mobilizon) lib/service/activity_pub/activity_pub.ex:122: Mobilizon.Service.ActivityPub.get_or_fetch_actor_by_url/2\n (mobilizon) lib/service/http_signatures/signature.ex:54: Mobilizon.Service.HTTPSignatures.Signature.get_public_key_for_url/1\n (mobilizon) lib/service/http_signatures/signature.ex:74: Mobilizon.Service.HTTPSignatures.Signature.fetch_public_key/1\n (http_signatures) lib/http_signatures/http_signatures.ex:40: HTTPSignatures.validate_conn/1\n (mobilizon) lib/mobilizon_web/http_signature.ex:45: Mobilizon.Web.HTTPSignaturePlug.call/2\n (mobilizon) Mobilizon.Web.Router.activity_pub_signature/2\n (mobilizon) lib/mobilizon_web/router.ex:1: Mobilizon.Web.Router.__pipe_through7__/1\n (phoenix) lib/phoenix/router.ex:283: Phoenix.Router.__call__/2\n (mobilizon) lib/mobilizon_web/endpoint.ex:1: Mobilizon.Web.Endpoint.plug_builder_call/2\n (mobilizon) lib/plug/debugger.ex:122: Mobilizon.Web.Endpoint.\"call (overridable 3)\"/2\n (mobilizon) lib/mobilizon_web/endpoint.ex:1: Mobilizon.Web.Endpoint.call/2\n (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:42: Phoenix.Endpoint.Cowboy2Handler.init/4\n (cowboy) /home/tcit/dev/frama/mobilizon/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2\n (cowboy) /home/tcit/dev/frama/mobilizon/deps/cowboy/src/cowboy_stream_h.erl:320: :cowboy_stream_h.execute/3\n (cowboy) /home/tcit/dev/frama/mobilizon/deps/cowboy/src/cowboy_stream_h.erl:302: :cowboy_stream_h.request_process/3\n (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3\n \n\n## Connection details\n\n### Params\n\n %{\"@context\" => [\"https://www.w3.org/ns/activitystreams\", \"https://litepub.social/litepub/context.jsonld\", %{\"Hashtag\" => \"as:Hashtag\", \"category\" => \"sc:category\", \"ical\" => \"http://www.w3.org/2002/12/cal/ical#\", \"joinMode\" => %{\"@id\" => \"mz:joinMode\", \"@type\" => \"mz:joinModeType\"}, \"joinModeType\" => %{\"@id\" => \"mz:joinModeType\", \"@type\" => \"rdfs:Class\"}, \"maximumAttendeeCapacity\" => \"sc:maximumAttendeeCapacity\", \"mz\" => \"https://joinmobilizon.org/ns#\", \"repliesModerationOption\" => %{\"@id\" => \"mz:repliesModerationOption\", \"@type\" => \"mz:repliesModerationOptionType\"}, \"repliesModerationOptionType\" => %{\"@id\" => \"mz:repliesModerationOptionType\", \"@type\" => \"rdfs:Class\"}, \"sc\" => \"http://schema.org#\", \"uuid\" => \"sc:identifier\"}], \"actor\" => \"http://mobilizon.test/relay\", \"cc\" => [\"https://www.w3.org/ns/activitystreams#Public\"], \"id\" => \"http://mobilizon.test/follow/57a6973e-f43f-4533-bf71-7a14a4c6e5ac\", \"object\" => \"http://mobilizon1.com/relay\", \"to\" => [\"http://mobilizon1.com/relay\"], \"type\" => \"Follow\"}\n\n### Request info\n\n * URI: http://mobilizon1.com:80/inbox\n * Query string: \n\n### Headers\n \n * connection: upgrade\n * content-length: 912\n * content-type: application/activity+json\n * date: Fri, 13 Dec 2019 09:41:40 GMT\n * digest: SHA-256=Qc9d9X3qh2EqIqtn/72iY17OMDXAOINDC10hARNAc4w=\n * host: mobilizon1.com\n * signature: keyId=\"http://mobilizon.test/relay#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-length date digest host\",signature=\"JQPqSiJ0ZYdU6llrYXNMuN/bfzoLyubwOB59bljFq6i8ORXLw62Pt7Jue5WkMsySFcCXgS8k8K/H81YZkKzfWadwQV9L5rQEFSuW/DYJ2xffsDj90GsSi+sDRaQ5Ke8nPEbEMGR9jalh/F2VL97XscCgm6i3tdpbs6aFmqjKC+LzeH665t0WCHUxTgK47wECrMHw3j7lteGdm6N6IKWoWsRYeJoyFr/QCbNdWQOaAYYpCbJd0fjhPQRHhWQXidBoaDkhwesWc3mO8pvEnply9ES7Nzc6ULK7B98hg+aWeep8/KzRbxFyJ0OgnDJj/l39QiJ9t7v0yHX/WUzn0CaiiQ==\"\n * user-agent: hackney/1.15.2\n * x-forwarded-for: 127.0.0.1\n * x-real-ip: 127.0.0.1\n\n### Session\n\n %{}\n",
|
|
||||||
"headers": {
|
|
||||||
"Server": "nginx/1.16.1",
|
|
||||||
"Date": "Fri, 13 Dec 2019 09:41:40 GMT",
|
|
||||||
"Content-Type": "text/markdown; charset=utf-8",
|
|
||||||
"Content-Length": "3977",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"access-control-allow-credentials": "true",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "Fd_k7MU4jVIgj4wAAAOB"
|
|
||||||
},
|
|
||||||
"status_code": 500,
|
|
||||||
"type": "ok"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -3,28 +3,81 @@
|
||||||
"request": {
|
"request": {
|
||||||
"body": "",
|
"body": "",
|
||||||
"headers": {
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "http://squeet.me/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>301 Moved Permanently</title>\n</head><body>\n<h1>Moved Permanently</h1>\n<p>The document has moved <a href=\"https://squeet.me/.well-known/host-meta\">here</a>.</p>\n<hr>\n<address>Apache/2.4.25 (Debian) Server at squeet.me Port 80</address>\n</body></html>\n",
|
||||||
|
"headers": {
|
||||||
|
"Date": "Fri, 09 Apr 2021 08:08:52 GMT",
|
||||||
|
"Server": "Apache/2.4.25 (Debian)",
|
||||||
|
"Location": "https://squeet.me/.well-known/host-meta",
|
||||||
|
"Content-Length": "322",
|
||||||
|
"Content-Type": "text/html; charset=iso-8859-1"
|
||||||
|
},
|
||||||
|
"status_code": 301,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "https://squeet.me/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<?xml version='1.0' encoding='UTF-8'?>\n<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'\n xmlns:hm='http://host-meta.net/xrd/1.0'>\n \n <hm:Host>squeet.me</hm:Host>\n \n <Link rel='lrdd' type='application/xrd+xml' template='https://squeet.me/xrd?uri={uri}' />\n <Link rel='lrdd' type='application/json' template='https://squeet.me/.well-known/webfinger?resource={uri}' />\n <Link rel='acct-mgmt' href='https://squeet.me/amcd' />\n <Link rel='http://services.mozilla.com/amcd/0.1' href='https://squeet.me/amcd' />\n\t<Link rel=\"http://oexchange.org/spec/0.8/rel/resident-target\" type=\"application/xrd+xml\" \n href=\"https://squeet.me/oexchange/xrd\" />\n\n <Property xmlns:mk=\"http://salmon-protocol.org/ns/magic-key\"\n type=\"http://salmon-protocol.org/ns/magic-key\"\n mk:key_id=\"1\">RSA.xlM2BNDH9hnO3W6vOUfJ5-tcUCaX-rx-kKydQd4ht21At4D4d1MrZ6nAQu7rnf5or9YZRhIpgvJvXBqWSo0zmALkUZUVrsS9WhH65I0qt24XNTPZJ1FdPDd7c1C131GzkymCbXBie3U2JaT7t0oimhWKUeA45gNfXk1T1l-7v4k.AQAB</Property>\n</XRD>\n",
|
||||||
|
"headers": {
|
||||||
|
"Date": "Fri, 09 Apr 2021 08:08:52 GMT",
|
||||||
|
"Server": "Apache/2.4.25 (Debian)",
|
||||||
|
"X-Account-Management-Status": "none",
|
||||||
|
"Vary": "Accept-Encoding",
|
||||||
|
"Transfer-Encoding": "chunked",
|
||||||
|
"Content-Type": "text/xml;charset=UTF-8"
|
||||||
|
},
|
||||||
|
"status_code": 200,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
"Accept": "application/json, application/activity+json, application/jrd+json"
|
||||||
},
|
},
|
||||||
"method": "get",
|
"method": "get",
|
||||||
"options": {
|
"options": {
|
||||||
"follow_redirect": "true"
|
"recv_timeout": 20000
|
||||||
},
|
},
|
||||||
"request_body": "",
|
"request_body": "",
|
||||||
"url": "http://squeet.me/.well-known/webfinger?resource=acct:lain@squeet.me"
|
"url": "https://squeet.me/.well-known/webfinger?resource=acct:lain@squeet.me"
|
||||||
},
|
},
|
||||||
"response": {
|
"response": {
|
||||||
"binary": false,
|
"binary": false,
|
||||||
"body": "{\"subject\":\"acct:lain@squeet.me\",\"aliases\":[\"https:\\/\\/squeet.me\\/~lain\",\"https:\\/\\/squeet.me\\/profile\\/lain\"],\"links\":[{\"rel\":\"http:\\/\\/purl.org\\/macgirvin\\/dfrn\\/1.0\",\"href\":\"https:\\/\\/squeet.me\\/profile\\/lain\"},{\"rel\":\"http:\\/\\/schemas.google.com\\/g\\/2010#updates-from\",\"type\":\"application\\/atom+xml\",\"href\":\"https:\\/\\/squeet.me\\/dfrn_poll\\/lain\"},{\"rel\":\"http:\\/\\/webfinger.net\\/rel\\/profile-page\",\"type\":\"text\\/html\",\"href\":\"https:\\/\\/squeet.me\\/profile\\/lain\"},{\"rel\":\"self\",\"type\":\"application\\/activity+json\",\"href\":\"https:\\/\\/squeet.me\\/profile\\/lain\"},{\"rel\":\"http:\\/\\/microformats.org\\/profile\\/hcard\",\"type\":\"text\\/html\",\"href\":\"https:\\/\\/squeet.me\\/hcard\\/lain\"},{\"rel\":\"http:\\/\\/portablecontacts.net\\/spec\\/1.0\",\"href\":\"https:\\/\\/squeet.me\\/poco\\/lain\"},{\"rel\":\"http:\\/\\/webfinger.net\\/rel\\/avatar\",\"type\":\"image\\/jpeg\",\"href\":\"https:\\/\\/squeet.me\\/photo\\/profile\\/301.jpg\"},{\"rel\":\"http:\\/\\/joindiaspora.com\\/seed_location\",\"type\":\"text\\/html\",\"href\":\"https:\\/\\/squeet.me\"},{\"rel\":\"salmon\",\"href\":\"https:\\/\\/squeet.me\\/salmon\\/lain\"},{\"rel\":\"http:\\/\\/salmon-protocol.org\\/ns\\/salmon-replies\",\"href\":\"https:\\/\\/squeet.me\\/salmon\\/lain\"},{\"rel\":\"http:\\/\\/salmon-protocol.org\\/ns\\/salmon-mention\",\"href\":\"https:\\/\\/squeet.me\\/salmon\\/lain\\/mention\"},{\"rel\":\"http:\\/\\/ostatus.org\\/schema\\/1.0\\/subscribe\",\"template\":\"https:\\/\\/squeet.me\\/follow?url={uri}\"},{\"rel\":\"magic-public-key\",\"href\":\"data:application\\/magic-public-key,RSA.AMwa8FUs2fWEjX0xN7yRQgegQffhBpuKNC6fa5VNSVorFjGZhRrlPMn7TQOeihlc9lBz2OsHlIedbYn2uJ7yCs0.AQAB\"},{\"rel\":\"http:\\/\\/purl.org\\/openwebauth\\/v1\",\"type\":\"application\\/x-dfrn+json\",\"href\":\"https:\\/\\/squeet.me\\/owa\"}]}",
|
"body": "{\"subject\":\"acct:lain@squeet.me\",\"aliases\":[\"https:\\/\\/squeet.me\\/~lain\",\"https:\\/\\/squeet.me\\/profile\\/lain\"],\"links\":[{\"rel\":\"http:\\/\\/purl.org\\/macgirvin\\/dfrn\\/1.0\",\"href\":\"https:\\/\\/squeet.me\\/profile\\/lain\"},{\"rel\":\"http:\\/\\/schemas.google.com\\/g\\/2010#updates-from\",\"type\":\"application\\/atom+xml\",\"href\":\"https:\\/\\/squeet.me\\/dfrn_poll\\/lain\"},{\"rel\":\"http:\\/\\/webfinger.net\\/rel\\/profile-page\",\"type\":\"text\\/html\",\"href\":\"https:\\/\\/squeet.me\\/profile\\/lain\"},{\"rel\":\"self\",\"type\":\"application\\/activity+json\",\"href\":\"https:\\/\\/squeet.me\\/profile\\/lain\"},{\"rel\":\"http:\\/\\/microformats.org\\/profile\\/hcard\",\"type\":\"text\\/html\",\"href\":\"https:\\/\\/squeet.me\\/hcard\\/lain\"},{\"rel\":\"http:\\/\\/portablecontacts.net\\/spec\\/1.0\",\"href\":\"https:\\/\\/squeet.me\\/poco\\/lain\"},{\"rel\":\"http:\\/\\/webfinger.net\\/rel\\/avatar\",\"type\":\"image\\/jpeg\",\"href\":\"https:\\/\\/squeet.me\\/photo\\/abf2ee40bfcb044ac7fd1d143c82f63a-4.jpg?ts=1526641378\"},{\"rel\":\"http:\\/\\/joindiaspora.com\\/seed_location\",\"type\":\"text\\/html\",\"href\":\"https:\\/\\/squeet.me\"},{\"rel\":\"salmon\",\"href\":\"https:\\/\\/squeet.me\\/salmon\\/lain\"},{\"rel\":\"http:\\/\\/salmon-protocol.org\\/ns\\/salmon-replies\",\"href\":\"https:\\/\\/squeet.me\\/salmon\\/lain\"},{\"rel\":\"http:\\/\\/salmon-protocol.org\\/ns\\/salmon-mention\",\"href\":\"https:\\/\\/squeet.me\\/salmon\\/lain\\/mention\"},{\"rel\":\"http:\\/\\/ostatus.org\\/schema\\/1.0\\/subscribe\",\"template\":\"https:\\/\\/squeet.me\\/follow?url={uri}\"},{\"rel\":\"magic-public-key\",\"href\":\"data:application\\/magic-public-key,RSA.zBrwVSzZ9YSNfTE3vJFCB6BB9-EGm4o0Lp9rlU1JWisWMZmFGuU8yftNA56KGVz2UHPY6weUh51tifa4nvIKzQ.AQAB\"},{\"rel\":\"http:\\/\\/purl.org\\/openwebauth\\/v1\",\"type\":\"application\\/x-zot+json\",\"href\":\"https:\\/\\/squeet.me\\/owa\"}]}",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Date": "Tue, 13 Nov 2018 11:11:09 GMT",
|
"Date": "Fri, 09 Apr 2021 08:08:52 GMT",
|
||||||
"Server": "Apache",
|
"Server": "Apache/2.4.25 (Debian)",
|
||||||
"Expires": "Thu, 19 Nov 1981 08:52:00 GMT",
|
|
||||||
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
||||||
"Pragma": "no-cache",
|
|
||||||
"X-Account-Management-Status": "none",
|
"X-Account-Management-Status": "none",
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
"Set-Cookie": "PHPSESSID=330arcps63iok272c5hqdsfhp3; path=/; secure; HttpOnly",
|
|
||||||
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
|
|
||||||
"Transfer-Encoding": "chunked",
|
"Transfer-Encoding": "chunked",
|
||||||
"Content-Type": "application/json; charset=utf-8"
|
"Content-Type": "application/json; charset=utf-8"
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,26 +3,26 @@
|
||||||
"request": {
|
"request": {
|
||||||
"body": "",
|
"body": "",
|
||||||
"headers": {
|
"headers": {
|
||||||
"User-Agent": "localhost - Mobilizon 1.0.0-rc.2-5-g6701e6a4",
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
},
|
},
|
||||||
"method": "get",
|
"method": "get",
|
||||||
"options": {
|
"options": {
|
||||||
"recv_timeout": 20000
|
"recv_timeout": 20000
|
||||||
},
|
},
|
||||||
"request_body": "",
|
"request_body": "",
|
||||||
"url": "http://social.tcit.fr/.well-known/webfinger?resource=acct:tcit@social.tcit.fr"
|
"url": "http://social.tcit.fr/.well-known/host-meta"
|
||||||
},
|
},
|
||||||
"response": {
|
"response": {
|
||||||
"binary": false,
|
"binary": false,
|
||||||
"body": "<html>\r\n<head><title>301 Moved Permanently</title></head>\r\n<body>\r\n<center><h1>301 Moved Permanently</h1></center>\r\n<hr><center>nginx/1.19.3</center>\r\n</body>\r\n</html>\r\n",
|
"body": "<html>\r\n<head><title>301 Moved Permanently</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>301 Moved Permanently</h1></center>\r\n<hr><center>nginx/1.14.2</center>\r\n</body>\r\n</html>\r\n",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Server": "nginx/1.19.3",
|
"Server": "nginx/1.14.2",
|
||||||
"Date": "Wed, 21 Oct 2020 09:07:41 GMT",
|
"Date": "Thu, 08 Apr 2021 18:59:56 GMT",
|
||||||
"Content-Type": "text/html",
|
"Content-Type": "text/html",
|
||||||
"Content-Length": "169",
|
"Content-Length": "185",
|
||||||
"Connection": "keep-alive",
|
"Connection": "keep-alive",
|
||||||
"Location": "https://social.tcit.fr/.well-known/webfinger?resource=acct:tcit@social.tcit.fr"
|
"Location": "https://social.tcit.fr/.well-known/host-meta"
|
||||||
},
|
},
|
||||||
"status_code": 301,
|
"status_code": 301,
|
||||||
"type": "ok"
|
"type": "ok"
|
||||||
|
@ -32,7 +32,47 @@
|
||||||
"request": {
|
"request": {
|
||||||
"body": "",
|
"body": "",
|
||||||
"headers": {
|
"headers": {
|
||||||
"User-Agent": "localhost - Mobilizon 1.0.0-rc.2-5-g6701e6a4",
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "https://social.tcit.fr/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<XRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\">\n <Link rel=\"lrdd\" template=\"https://social.tcit.fr/.well-known/webfinger?resource={uri}\"/>\n</XRD>\n",
|
||||||
|
"headers": {
|
||||||
|
"Date": "Thu, 08 Apr 2021 18:59:56 GMT",
|
||||||
|
"Content-Type": "application/xrd+xml; charset=utf-8",
|
||||||
|
"Transfer-Encoding": "chunked",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Server": "Mastodon",
|
||||||
|
"X-Frame-Options": "DENY",
|
||||||
|
"X-Content-Type-Options": "nosniff",
|
||||||
|
"X-XSS-Protection": "1; mode=block",
|
||||||
|
"Referrer-Policy": "same-origin",
|
||||||
|
"Strict-Transport-Security": "max-age=63072000; includeSubDomains; preload",
|
||||||
|
"X-Clacks-Overhead": "GNU Natalie Nguyen",
|
||||||
|
"Vary": "Accept, Accept-Encoding, Origin",
|
||||||
|
"Cache-Control": "max-age=259200, public",
|
||||||
|
"ETag": "W/\"b397089bfee005b03360ba4435bb4aad\"",
|
||||||
|
"X-Request-Id": "41e837ba-21a6-4324-bda8-cac28a8d1778",
|
||||||
|
"X-Runtime": "0.004198",
|
||||||
|
"X-Cached": "MISS"
|
||||||
|
},
|
||||||
|
"status_code": 200,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
"Accept": "application/json, application/activity+json, application/jrd+json"
|
||||||
},
|
},
|
||||||
"method": "get",
|
"method": "get",
|
||||||
|
@ -46,7 +86,7 @@
|
||||||
"binary": false,
|
"binary": false,
|
||||||
"body": "{\"subject\":\"acct:tcit@social.tcit.fr\",\"aliases\":[\"https://social.tcit.fr/@tcit\",\"https://social.tcit.fr/users/tcit\"],\"links\":[{\"rel\":\"http://webfinger.net/rel/profile-page\",\"type\":\"text/html\",\"href\":\"https://social.tcit.fr/@tcit\"},{\"rel\":\"self\",\"type\":\"application/activity+json\",\"href\":\"https://social.tcit.fr/users/tcit\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://social.tcit.fr/authorize_interaction?uri={uri}\"}]}",
|
"body": "{\"subject\":\"acct:tcit@social.tcit.fr\",\"aliases\":[\"https://social.tcit.fr/@tcit\",\"https://social.tcit.fr/users/tcit\"],\"links\":[{\"rel\":\"http://webfinger.net/rel/profile-page\",\"type\":\"text/html\",\"href\":\"https://social.tcit.fr/@tcit\"},{\"rel\":\"self\",\"type\":\"application/activity+json\",\"href\":\"https://social.tcit.fr/users/tcit\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://social.tcit.fr/authorize_interaction?uri={uri}\"}]}",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Date": "Wed, 21 Oct 2020 09:07:41 GMT",
|
"Date": "Thu, 08 Apr 2021 18:59:56 GMT",
|
||||||
"Content-Type": "application/jrd+json; charset=utf-8",
|
"Content-Type": "application/jrd+json; charset=utf-8",
|
||||||
"Transfer-Encoding": "chunked",
|
"Transfer-Encoding": "chunked",
|
||||||
"Connection": "keep-alive",
|
"Connection": "keep-alive",
|
||||||
|
@ -60,8 +100,8 @@
|
||||||
"Vary": "Accept, Accept-Encoding, Origin",
|
"Vary": "Accept, Accept-Encoding, Origin",
|
||||||
"Cache-Control": "max-age=259200, public",
|
"Cache-Control": "max-age=259200, public",
|
||||||
"ETag": "W/\"37760e35c1537b8e02b6d4b4f9ebfe82\"",
|
"ETag": "W/\"37760e35c1537b8e02b6d4b4f9ebfe82\"",
|
||||||
"X-Request-Id": "429bb891-1033-498b-91bb-12835984223f",
|
"X-Request-Id": "4c8384d6-d921-4ef6-8a18-1fcbf35ee6bc",
|
||||||
"X-Runtime": "0.072046",
|
"X-Runtime": "0.009277",
|
||||||
"X-Cached": "MISS"
|
"X-Cached": "MISS"
|
||||||
},
|
},
|
||||||
"status_code": 200,
|
"status_code": 200,
|
||||||
|
|
|
@ -3,33 +3,88 @@
|
||||||
"request": {
|
"request": {
|
||||||
"body": "",
|
"body": "",
|
||||||
"headers": {
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "http://framatube.org/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<html>\r\n<head><title>301 Moved Permanently</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>301 Moved Permanently</h1></center>\r\n<hr><center>nginx/1.14.2</center>\r\n</body>\r\n</html>\r\n",
|
||||||
|
"headers": {
|
||||||
|
"Server": "nginx/1.14.2",
|
||||||
|
"Date": "Thu, 08 Apr 2021 18:59:59 GMT",
|
||||||
|
"Content-Type": "text/html",
|
||||||
|
"Content-Length": "185",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Location": "https://framatube.org/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"status_code": 301,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "https://framatube.org/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<XRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\">\n <Link rel=\"lrdd\" type=\"application/xrd+xml\" template=\"https://framatube.org/.well-known/webfinger?resource={uri}\"/>\n</XRD>",
|
||||||
|
"headers": {
|
||||||
|
"Server": "nginx/1.14.2",
|
||||||
|
"Date": "Thu, 08 Apr 2021 18:59:59 GMT",
|
||||||
|
"Content-Type": "application/xml; charset=utf-8",
|
||||||
|
"Content-Length": "219",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Tk": "N",
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
"ETag": "W/\"db-l6RCFQ8UK40DPZ9VQ8G/SKn3A64\""
|
||||||
|
},
|
||||||
|
"status_code": 200,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
"Accept": "application/json, application/activity+json, application/jrd+json"
|
||||||
},
|
},
|
||||||
"method": "get",
|
"method": "get",
|
||||||
"options": {
|
"options": {
|
||||||
"follow_redirect": "true"
|
"recv_timeout": 20000
|
||||||
},
|
},
|
||||||
"request_body": "",
|
"request_body": "",
|
||||||
"url": "http://framatube.org/.well-known/webfinger?resource=acct:framasoft@framatube.org"
|
"url": "https://framatube.org/.well-known/webfinger?resource=acct:framasoft@framatube.org"
|
||||||
},
|
},
|
||||||
"response": {
|
"response": {
|
||||||
"binary": false,
|
"binary": false,
|
||||||
"body": "{\"subject\":\"acct:framasoft@framatube.org\",\"aliases\":[\"https://framatube.org/accounts/framasoft\"],\"links\":[{\"rel\":\"self\",\"type\":\"application/activity+json\",\"href\":\"https://framatube.org/accounts/framasoft\"}]}",
|
"body": "{\"subject\":\"acct:framasoft@framatube.org\",\"aliases\":[\"https://framatube.org/accounts/framasoft\"],\"links\":[{\"rel\":\"self\",\"type\":\"application/activity+json\",\"href\":\"https://framatube.org/accounts/framasoft\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://framatube.org/remote-interaction?uri={uri}\"}]}",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Server": "nginx/1.10.3",
|
"Server": "nginx/1.14.2",
|
||||||
"Date": "Tue, 13 Nov 2018 11:11:11 GMT",
|
"Date": "Thu, 08 Apr 2021 18:59:59 GMT",
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
"Content-Length": "207",
|
"Content-Length": "321",
|
||||||
"Connection": "keep-alive",
|
"Connection": "keep-alive",
|
||||||
"X-DNS-Prefetch-Control": "off",
|
|
||||||
"X-Frame-Options": "DENY",
|
|
||||||
"X-Download-Options": "noopen",
|
|
||||||
"X-Content-Type-Options": "nosniff",
|
|
||||||
"X-XSS-Protection": "1; mode=block",
|
|
||||||
"Tk": "N",
|
"Tk": "N",
|
||||||
"ETag": "W/\"cf-VoWlsif7OQ4xxqki7jRAnOPKRes\"",
|
"Access-Control-Allow-Origin": "*",
|
||||||
"Strict-Transport-Security": "max-age=63072000; includeSubDomains; preload",
|
"ETag": "W/\"141-yxvvlAPayX5y2q2Yra8qYVtz4VU\""
|
||||||
"X-Robots-Tag": "none"
|
|
||||||
},
|
},
|
||||||
"status_code": 200,
|
"status_code": 200,
|
||||||
"type": "ok"
|
"type": "ok"
|
||||||
|
|
105
test/fixtures/vcr_cassettes/webfinger/pleroma.json
vendored
105
test/fixtures/vcr_cassettes/webfinger/pleroma.json
vendored
|
@ -3,38 +3,107 @@
|
||||||
"request": {
|
"request": {
|
||||||
"body": "",
|
"body": "",
|
||||||
"headers": {
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "http://pleroma.soykaf.com/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<html>\r\n<head><title>301 Moved Permanently</title></head>\r\n<body>\r\n<center><h1>301 Moved Permanently</h1></center>\r\n<hr><center>nginx/1.18.0 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n",
|
||||||
|
"headers": {
|
||||||
|
"Server": "nginx/1.18.0 (Ubuntu)",
|
||||||
|
"Date": "Thu, 08 Apr 2021 18:59:57 GMT",
|
||||||
|
"Content-Type": "text/html",
|
||||||
|
"Content-Length": "178",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Location": "https://pleroma.soykaf.com/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"status_code": 301,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
|
"Accept": "application/xrd+xml, application/xml, text/xml"
|
||||||
|
},
|
||||||
|
"method": "get",
|
||||||
|
"options": {
|
||||||
|
"recv_timeout": 20000
|
||||||
|
},
|
||||||
|
"request_body": "",
|
||||||
|
"url": "https://pleroma.soykaf.com/.well-known/host-meta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"binary": false,
|
||||||
|
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><XRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\"><Link rel=\"lrdd\" template=\"https://pleroma.soykaf.com/.well-known/webfinger?resource={uri}\" type=\"application/xrd+xml\" /></XRD>",
|
||||||
|
"headers": {
|
||||||
|
"Server": "nginx/1.18.0 (Ubuntu)",
|
||||||
|
"Date": "Thu, 08 Apr 2021 18:59:57 GMT",
|
||||||
|
"Content-Type": "application/xrd+xml; charset=utf-8",
|
||||||
|
"Content-Length": "220",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"access-control-allow-credentials": "true",
|
||||||
|
"access-control-allow-origin": "*",
|
||||||
|
"access-control-expose-headers": "Link,X-RateLimit-Reset,X-RateLimit-Limit,X-RateLimit-Remaining,X-Request-Id,Idempotency-Key",
|
||||||
|
"cache-control": "max-age=0, private, must-revalidate",
|
||||||
|
"content-security-policy": "upgrade-insecure-requests;script-src 'self';connect-src 'self' blob: https://pleroma.soykaf.com wss://pleroma.soykaf.com;media-src 'self';img-src 'self' data: blob:;default-src 'none';base-uri 'self';frame-ancestors 'none';style-src 'self' 'unsafe-inline';font-src 'self';manifest-src 'self';",
|
||||||
|
"referrer-policy": "same-origin",
|
||||||
|
"x-content-type-options": "nosniff",
|
||||||
|
"x-download-options": "noopen",
|
||||||
|
"x-frame-options": "DENY",
|
||||||
|
"x-permitted-cross-domain-policies": "none",
|
||||||
|
"x-request-id": "FnP3HZA8tRWC7E4EYzyS",
|
||||||
|
"x-xss-protection": "1; mode=block"
|
||||||
|
},
|
||||||
|
"status_code": 200,
|
||||||
|
"type": "ok"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"request": {
|
||||||
|
"body": "",
|
||||||
|
"headers": {
|
||||||
|
"User-Agent": "localhost - Mobilizon 1.1.0-32-gbd53bfc4-dirty",
|
||||||
"Accept": "application/json, application/activity+json, application/jrd+json"
|
"Accept": "application/json, application/activity+json, application/jrd+json"
|
||||||
},
|
},
|
||||||
"method": "get",
|
"method": "get",
|
||||||
"options": {
|
"options": {
|
||||||
"follow_redirect": "true"
|
"recv_timeout": 20000
|
||||||
},
|
},
|
||||||
"request_body": "",
|
"request_body": "",
|
||||||
"url": "http://pleroma.soykaf.com/.well-known/webfinger?resource=acct:lain@pleroma.soykaf.com"
|
"url": "https://pleroma.soykaf.com/.well-known/webfinger?resource=acct:lain@pleroma.soykaf.com"
|
||||||
},
|
},
|
||||||
"response": {
|
"response": {
|
||||||
"binary": false,
|
"binary": false,
|
||||||
"body": "{\"aliases\":[\"https://pleroma.soykaf.com/users/lain\"],\"links\":[{\"href\":\"https://pleroma.soykaf.com/users/lain/feed.atom\",\"rel\":\"http://schemas.google.com/g/2010#updates-from\",\"type\":\"application/atom+xml\"},{\"href\":\"https://pleroma.soykaf.com/users/lain\",\"rel\":\"http://webfinger.net/rel/profile-page\",\"type\":\"text/html\"},{\"href\":\"https://pleroma.soykaf.com/users/lain/salmon\",\"rel\":\"salmon\"},{\"href\":\"data:application/magic-public-key,RSA.u39dKLin8N4PywPvasEGXstOMsgg9m1OEKnpfHnSHqc6UOtIPs5-aI_LcLbhIEH2EVl6jstvtqMIloPch1FizZ3OBiKz81dXTiEZ3NfKgj_GJfIlipChAadxrmUyWT_Pr0qPaF1vhPrkSTwR8iDNUiQ-OEggRPpJVkJ619MXNdsJE59yklZiD1WY0vC9aG9m-dh0BANKNwSjwfZ3uFjDh0UosMATKjPTSO_I59nK_lArex_jAwTnVm6Dryk2qR2XXZyzTzZAHuYqSM77RlsNTJUCOaSadl816eZAvU3TF-ibIou0D-0sN-M-QehRh93sVJ95U40GQz8jOGc_5wK8xw==.AQAB\",\"rel\":\"magic-public-key\"},{\"href\":\"https://pleroma.soykaf.com/users/lain\",\"rel\":\"self\",\"type\":\"application/activity+json\"},{\"href\":\"https://pleroma.soykaf.com/users/lain\",\"rel\":\"self\",\"type\":\"application/ld+json; profile=\\\"https://www.w3.org/ns/activitystreams\\\"\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://pleroma.soykaf.com/ostatus_subscribe?acct={uri}\"}],\"subject\":\"acct:lain@pleroma.soykaf.com\"}",
|
"body": "{\"aliases\":[\"https://pleroma.soykaf.com/users/lain\"],\"links\":[{\"href\":\"https://pleroma.soykaf.com/users/lain\",\"rel\":\"http://webfinger.net/rel/profile-page\",\"type\":\"text/html\"},{\"href\":\"https://pleroma.soykaf.com/users/lain\",\"rel\":\"self\",\"type\":\"application/activity+json\"},{\"href\":\"https://pleroma.soykaf.com/users/lain\",\"rel\":\"self\",\"type\":\"application/ld+json; profile=\\\"https://www.w3.org/ns/activitystreams\\\"\"},{\"rel\":\"http://ostatus.org/schema/1.0/subscribe\",\"template\":\"https://pleroma.soykaf.com/ostatus_subscribe?acct={uri}\"}],\"subject\":\"acct:lain@pleroma.soykaf.com\"}",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Server": "nginx/1.10.3",
|
"Server": "nginx/1.18.0 (Ubuntu)",
|
||||||
"Date": "Tue, 13 Nov 2018 11:11:11 GMT",
|
"Date": "Thu, 08 Apr 2021 18:59:57 GMT",
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
"Content-Type": "application/json; charset=utf-8",
|
||||||
"Content-Length": "1214",
|
"Content-Length": "576",
|
||||||
"Connection": "keep-alive",
|
"Connection": "keep-alive",
|
||||||
"Vary": "Accept-Encoding",
|
"Vary": "Accept-Encoding",
|
||||||
"cache-control": "max-age=0, private, must-revalidate",
|
|
||||||
"x-request-id": "2ljal4oljell0gfni41am571",
|
|
||||||
"access-control-allow-origin": "*",
|
|
||||||
"access-control-expose-headers": "",
|
|
||||||
"access-control-allow-credentials": "true",
|
"access-control-allow-credentials": "true",
|
||||||
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
|
"access-control-allow-origin": "*",
|
||||||
"Access-Control-Allow-Headers": "Authorization, Content-Type",
|
"access-control-expose-headers": "Link,X-RateLimit-Reset,X-RateLimit-Limit,X-RateLimit-Remaining,X-Request-Id,Idempotency-Key",
|
||||||
"X-XSS-Protection": "1; mode=block",
|
"cache-control": "max-age=0, private, must-revalidate",
|
||||||
"X-Permitted-Cross-Domain-Policies": "none",
|
"content-security-policy": "upgrade-insecure-requests;script-src 'self';connect-src 'self' blob: https://pleroma.soykaf.com wss://pleroma.soykaf.com;media-src 'self';img-src 'self' data: blob:;default-src 'none';base-uri 'self';frame-ancestors 'none';style-src 'self' 'unsafe-inline';font-src 'self';manifest-src 'self';",
|
||||||
"X-Frame-Options": "DENY",
|
"referrer-policy": "same-origin",
|
||||||
"X-Content-Type-Options": "nosniff",
|
"x-content-type-options": "nosniff",
|
||||||
"Referrer-Policy": "same-origin",
|
"x-download-options": "noopen",
|
||||||
"X-Download-Options": "noopen"
|
"x-frame-options": "DENY",
|
||||||
|
"x-permitted-cross-domain-policies": "none",
|
||||||
|
"x-request-id": "FnP3HZJ_kh8ymy8E1OCx",
|
||||||
|
"x-xss-protection": "1; mode=block"
|
||||||
},
|
},
|
||||||
"status_code": 200,
|
"status_code": 200,
|
||||||
"type": "ok"
|
"type": "ok"
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule Mix.Tasks.Mobilizon.ActorsTest do
|
||||||
|
|
||||||
@username "someone"
|
@username "someone"
|
||||||
@domain "somewhere.tld"
|
@domain "somewhere.tld"
|
||||||
|
@error "Error: No such actor"
|
||||||
|
|
||||||
describe "show actor" do
|
describe "show actor" do
|
||||||
test "show existing local actor" do
|
test "show existing local actor" do
|
||||||
|
@ -50,7 +51,7 @@ defmodule Mix.Tasks.Mobilizon.ActorsTest do
|
||||||
test "show non-existing actor" do
|
test "show non-existing actor" do
|
||||||
Show.run([@username])
|
Show.run([@username])
|
||||||
assert_received {:mix_shell, :error, [message]}
|
assert_received {:mix_shell, :error, [message]}
|
||||||
assert message =~ "Error: No such actor"
|
assert message =~ @error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,52 +3,73 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Mix.Tasks.Mobilizon.RelayTest do
|
defmodule Mix.Tasks.Mobilizon.RelayTest do
|
||||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
|
||||||
|
|
||||||
use Mobilizon.DataCase
|
use Mobilizon.DataCase
|
||||||
|
|
||||||
alias Mobilizon.Actors
|
|
||||||
alias Mobilizon.Actors.{Actor, Follower}
|
|
||||||
alias Mix.Tasks.Mobilizon.Relay.{Follow, Unfollow}
|
alias Mix.Tasks.Mobilizon.Relay.{Follow, Unfollow}
|
||||||
|
|
||||||
alias Mobilizon.Federation.ActivityPub.Relay
|
alias Mobilizon.Federation.ActivityPub.Relay
|
||||||
|
import Mock
|
||||||
|
|
||||||
|
Mix.shell(Mix.Shell.Process)
|
||||||
|
|
||||||
|
@target_instance "mobilizon1.com"
|
||||||
|
|
||||||
|
@output_1 "Requested to follow #{@target_instance}"
|
||||||
|
@error_1 "Some error"
|
||||||
|
@error_msg_1 "Error while following #{@target_instance}: \"#{@error_1}\""
|
||||||
|
@error_msg_1_unfollow "Error while unfollowing #{@target_instance}: \"#{@error_1}\""
|
||||||
|
@error_msg_2 "mobilizon.relay.follow requires an instance hostname as arguments"
|
||||||
|
@error_msg_2_unfollow "mobilizon.relay.unfollow requires an instance hostname as arguments"
|
||||||
|
|
||||||
|
@output_2 "Unfollowed #{@target_instance}"
|
||||||
|
|
||||||
describe "running follow" do
|
describe "running follow" do
|
||||||
test "relay is followed" do
|
test "relay is followed" do
|
||||||
use_cassette "relay/fetch_relay_follow" do
|
with_mock Relay, [:passthrough], follow: fn @target_instance -> {:ok, nil, nil} end do
|
||||||
target_instance = "mobilizon1.com"
|
Follow.run([@target_instance])
|
||||||
|
assert_received {:mix_shell, :info, [output_received]}
|
||||||
Follow.run([target_instance])
|
assert output_received == @output_1
|
||||||
|
|
||||||
local_actor = Relay.get_actor()
|
|
||||||
assert local_actor.url =~ "/relay"
|
|
||||||
|
|
||||||
{:ok, target_actor} = Actors.get_actor_by_url("http://#{target_instance}/relay")
|
|
||||||
refute is_nil(target_actor.domain)
|
|
||||||
|
|
||||||
assert Actors.is_following(local_actor, target_actor)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "returns an error" do
|
||||||
|
with_mock Relay, [:passthrough], follow: fn @target_instance -> {:error, @error_1} end do
|
||||||
|
Follow.run([@target_instance])
|
||||||
|
assert_received {:mix_shell, :error, [output_received]}
|
||||||
|
assert output_received == @error_msg_1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "without arguments" do
|
||||||
|
Follow.run([])
|
||||||
|
assert_received {:mix_shell, :error, [output_received]}
|
||||||
|
assert output_received == @error_msg_2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "running unfollow" do
|
describe "running unfollow" do
|
||||||
test "relay is unfollowed" do
|
test "relay is unfollowed" do
|
||||||
use_cassette "relay/fetch_relay_unfollow" do
|
with_mock Relay, [:passthrough], unfollow: fn @target_instance -> {:ok, nil, nil} end do
|
||||||
target_instance = "mobilizon1.com"
|
Unfollow.run([@target_instance])
|
||||||
|
|
||||||
Follow.run([target_instance])
|
assert_received {:mix_shell, :info, [output_received]}
|
||||||
|
assert output_received == @output_2
|
||||||
%Actor{} = local_actor = Relay.get_actor()
|
|
||||||
|
|
||||||
{:ok, %Actor{} = target_actor} =
|
|
||||||
Actors.get_actor_by_url("http://#{target_instance}/relay")
|
|
||||||
|
|
||||||
assert %Follower{} = Actors.is_following(local_actor, target_actor)
|
|
||||||
|
|
||||||
Unfollow.run([target_instance])
|
|
||||||
|
|
||||||
refute Actors.is_following(local_actor, target_actor)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "returns an error" do
|
||||||
|
with_mock Relay, [:passthrough], unfollow: fn @target_instance -> {:error, @error_1} end do
|
||||||
|
Unfollow.run([@target_instance])
|
||||||
|
|
||||||
|
assert_received {:mix_shell, :error, [output_received]}
|
||||||
|
assert output_received == @error_msg_1_unfollow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "without arguments" do
|
||||||
|
Unfollow.run([])
|
||||||
|
assert_received {:mix_shell, :error, [output_received]}
|
||||||
|
assert output_received == @error_msg_2_unfollow
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,9 +23,9 @@ defmodule Mobilizon.Web.WebFingerControllerTest do
|
||||||
conn = get(conn, "/.well-known/host-meta")
|
conn = get(conn, "/.well-known/host-meta")
|
||||||
|
|
||||||
assert response(conn, 200) ==
|
assert response(conn, 200) ==
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><XRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\"><Link rel=\"lrdd\" template=\"#{
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><XRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\" xmlns:hm=\"http://host-meta.net/ns/1.0\"><hm:Host>mobilizon.test</hm:Host><Link rel=\"lrdd\" template=\"#{
|
||||||
Endpoint.url()
|
Endpoint.url()
|
||||||
}/.well-known/webfinger?resource={uri}\" type=\"application/xrd+xml\" /></XRD>"
|
}/.well-known/webfinger?resource={uri}\" type=\"application/jrd+json\" /></XRD>"
|
||||||
|
|
||||||
assert {"content-type", "application/xrd+xml; charset=utf-8"} in conn.resp_headers
|
assert {"content-type", "application/xrd+xml; charset=utf-8"} in conn.resp_headers
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue