Merge branch 'fixes' into 'master'

More fixes

See merge request framasoft/mobilizon!889
This commit is contained in:
Thomas Citharel 2021-04-12 12:09:49 +00:00
commit de7ad98cd5
53 changed files with 943 additions and 480 deletions

View file

@ -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,

View file

@ -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>

View file

@ -75,6 +75,11 @@ export const CONFIG = gql`
label label
} }
} }
uploadLimits {
default
avatar
banner
}
} }
} }
`; `;

View file

@ -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"
} }

View file

@ -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"
} }

View file

@ -89,4 +89,9 @@ export interface IConfig {
ldap: boolean; ldap: boolean;
oauthProviders: IOAuthProvider[]; oauthProviders: IOAuthProvider[];
}; };
uploadLimits: {
default: number;
avatar: number;
banner: number;
};
} }

View file

@ -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);

View file

@ -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
)
); );
} }
} }

View file

@ -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>

View file

@ -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",
});
} }
} }
); );

View file

@ -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,
},
}, },
}, },
}; };

View file

@ -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 ->

View file

@ -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

View file

@ -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

View file

@ -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 ->

View file

@ -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

View file

@ -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

View file

@ -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}),

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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}

View file

@ -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?()

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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"}
]) ])

View file

@ -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
) )

View file

@ -0,0 +1,4 @@
defimpl Plug.Exception, for: Phoenix.NotAcceptableError do
def status(_exception), do: 406
def actions(_exception), do: []
end

View file

@ -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]},

View file

@ -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"},

View file

@ -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

View file

@ -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"
}
}
]

View file

@ -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"
}
}
]

View file

@ -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"
}, },

View file

@ -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,

View file

@ -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"

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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