Allow to edit account email and delete account

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-02-13 15:48:12 +01:00
parent 9fc3c7017f
commit 9f007da286
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
44 changed files with 2262 additions and 590 deletions

View File

@ -18,6 +18,8 @@ Also make sure to remove the `EnvironmentFile=` line from the systemd service an
### Added ### Added
- Possibility to participate anonymously to an event - Possibility to participate anonymously to an event
- Possibility to participate to a remote event (being redirected by providing federated identity) - Possibility to participate to a remote event (being redirected by providing federated identity)
- Possibility to change email address for the account
- Possibility to delete your account
### Fixed ### Fixed
- Fixed URL search - Fixed URL search

View File

@ -66,7 +66,8 @@ export default class ParticipationWithAccount extends Vue {
} }
private async webFingerFetch(hostname: string, identity: string): Promise<string> { private async webFingerFetch(hostname: string, identity: string): Promise<string> {
const data = await ((await fetch(`http://${hostname}/.well-known/webfinger?resource=acct:${identity}`)).json()); const scheme = process.env.NODE_ENV === 'production' ? 'https' : 'http';
const data = await ((await fetch(`${scheme}://${hostname}/.well-known/webfinger?resource=acct:${identity}`)).json());
if (data && Array.isArray(data.links)) { if (data && Array.isArray(data.links)) {
const link: { template: string } = data.links.find((link: any) => { const link: { template: string } = data.links.find((link: any) => {
return link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe'; return link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe';

View File

@ -30,6 +30,15 @@ mutation ValidateUser($token: String!) {
} }
`; `;
export const LOGGED_USER = gql`
query {
loggedUser {
id,
email
}
}
`;
export const CHANGE_PASSWORD = gql` export const CHANGE_PASSWORD = gql`
mutation ChangePassword($oldPassword: String!, $newPassword: String!) { mutation ChangePassword($oldPassword: String!, $newPassword: String!) {
changePassword(oldPassword: $oldPassword, newPassword: $newPassword) { changePassword(oldPassword: $oldPassword, newPassword: $newPassword) {
@ -38,6 +47,32 @@ export const CHANGE_PASSWORD = gql`
} }
`; `;
export const CHANGE_EMAIL = gql`
mutation ChangeEmail($email: String!, $password: String!) {
changeEmail(email: $email, password: $password) {
id
}
}
`;
export const VALIDATE_EMAIL = gql`
mutation ValidateEmail($token: String!) {
validateEmail(
token: $token
) {
id
}
}
`;
export const DELETE_ACCOUNT = gql`
mutation DeleteAccount($password: String!) {
deleteAccount (password: $password) {
id
}
}
`;
export const CURRENT_USER_CLIENT = gql` export const CURRENT_USER_CLIENT = gql`
query { query {
currentUser @client { currentUser @client {

View File

@ -8,6 +8,7 @@
"About this instance": "About this instance", "About this instance": "About this instance",
"About": "About", "About": "About",
"Accepted": "Accepted", "Accepted": "Accepted",
"Account settings": "Account settings",
"Add a note": "Add a note", "Add a note": "Add a note",
"Add an address": "Add an address", "Add an address": "Add an address",
"Add an instance": "Add an instance", "Add an instance": "Add an instance",
@ -26,6 +27,7 @@
"Anonymous participants will be asked to confirm their participation through e-mail.": "Anonymous participants will be asked to confirm their participation through e-mail.", "Anonymous participants will be asked to confirm their participation through e-mail.": "Anonymous participants will be asked to confirm their participation through e-mail.",
"Anonymous participations": "Anonymous participations", "Anonymous participations": "Anonymous participations",
"Approve": "Approve", "Approve": "Approve",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Are you sure you want to <b>delete</b> this comment? This action cannot be undone.", "Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Are you sure you want to <b>delete</b> this comment? This action cannot be undone.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.", "Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Are you sure you want to cancel the event creation? You'll lose all modifications.", "Are you sure you want to cancel the event creation? You'll lose all modifications.": "Are you sure you want to cancel the event creation? You'll lose all modifications.",
@ -44,9 +46,9 @@
"Cancel": "Cancel", "Cancel": "Cancel",
"Cancelled: Won't happen": "Cancelled: Won't happen", "Cancelled: Won't happen": "Cancelled: Won't happen",
"Category": "Category", "Category": "Category",
"Change my email": "Change my email",
"Change my identity…": "Change my identity…", "Change my identity…": "Change my identity…",
"Change my password": "Change my password", "Change my password": "Change my password",
"Change password": "Change password",
"Change": "Change", "Change": "Change",
"Clear": "Clear", "Clear": "Clear",
"Click to select": "Click to select", "Click to select": "Click to select",
@ -86,7 +88,10 @@
"Default": "Default", "Default": "Default",
"Delete Comment": "Delete Comment", "Delete Comment": "Delete Comment",
"Delete Event": "Delete Event", "Delete Event": "Delete Event",
"Delete account": "Delete account",
"Delete event": "Delete event", "Delete event": "Delete event",
"Delete everything": "Delete everything",
"Delete my account": "Delete my account",
"Delete this identity": "Delete this identity", "Delete this identity": "Delete this identity",
"Delete your identity": "Delete your identity", "Delete your identity": "Delete your identity",
"Delete {eventTitle}": "Delete {eventTitle}", "Delete {eventTitle}": "Delete {eventTitle}",
@ -94,6 +99,8 @@
"Delete": "Delete", "Delete": "Delete",
"Deleting comment": "Deleting comment", "Deleting comment": "Deleting comment",
"Deleting event": "Deleting event", "Deleting event": "Deleting event",
"Deleting my account will delete all of my identities.": "Deleting my account will delete all of my identities.",
"Deleting your Mobilizon account": "Deleting your Mobilizon account",
"Description": "Description", "Description": "Description",
"Didn't receive the instructions ?": "Didn't receive the instructions ?", "Didn't receive the instructions ?": "Didn't receive the instructions ?",
"Display name": "Display name", "Display name": "Display name",
@ -105,12 +112,14 @@
"Eg: Stockholm, Dance, Chess…": "Eg: Stockholm, Dance, Chess…", "Eg: Stockholm, Dance, Chess…": "Eg: Stockholm, Dance, Chess…",
"Either on the {instance} instance or on another instance.": "Either on the {instance} instance or on another instance.", "Either on the {instance} instance or on another instance.": "Either on the {instance} instance or on another instance.",
"Either the account is already validated, either the validation token is incorrect.": "Either the account is already validated, either the validation token is incorrect.", "Either the account is already validated, either the validation token is incorrect.": "Either the account is already validated, either the validation token is incorrect.",
"Either the email has already been changed, either the validation token is incorrect.": "Either the email has already been changed, either the validation token is incorrect.",
"Either the participation has already been validated, either the validation token is incorrect.": "Either the participation has already been validated, either the validation token is incorrect.", "Either the participation has already been validated, either the validation token is incorrect.": "Either the participation has already been validated, either the validation token is incorrect.",
"Email": "Email", "Email": "Email",
"Ends on…": "Ends on…", "Ends on…": "Ends on…",
"Enjoy discovering Mobilizon!": "Enjoy discovering Mobilizon!", "Enjoy discovering Mobilizon!": "Enjoy discovering Mobilizon!",
"Enter the link URL": "Enter the link URL", "Enter the link URL": "Enter the link URL",
"Enter your own terms. HTML tags allowed. Mobilizon.org's terms are provided as template.": "Enter your own terms. HTML tags allowed. Mobilizon.org's terms are provided as template.", "Enter your own terms. HTML tags allowed. Mobilizon.org's terms are provided as template.": "Enter your own terms. HTML tags allowed. Mobilizon.org's terms are provided as template.",
"Error while changing email": "Error while changing email",
"Error while communicating with the server.": "Error while communicating with the server.", "Error while communicating with the server.": "Error while communicating with the server.",
"Error while saving report.": "Error while saving report.", "Error while saving report.": "Error while saving report.",
"Error while validating account": "Error while validating account", "Error while validating account": "Error while validating account",
@ -205,6 +214,7 @@
"My events": "My events", "My events": "My events",
"My identities": "My identities", "My identities": "My identities",
"Name": "Name", "Name": "Name",
"New email": "New email",
"New note": "New note", "New note": "New note",
"New password": "New password", "New password": "New password",
"No actors found": "No actors found", "No actors found": "No actors found",
@ -253,7 +263,6 @@
"Participation approval": "Participation approval", "Participation approval": "Participation approval",
"Participation requested!": "Participation requested!", "Participation requested!": "Participation requested!",
"Password (confirmation)": "Password (confirmation)", "Password (confirmation)": "Password (confirmation)",
"Password change": "Password change",
"Password reset": "Password reset", "Password reset": "Password reset",
"Password": "Password", "Password": "Password",
"Past events": "Passed events", "Past events": "Passed events",
@ -261,6 +270,7 @@
"Pick an identity": "Pick an identity", "Pick an identity": "Pick an identity",
"Please check your spam folder if you didn't receive the email.": "Please check your spam folder if you didn't receive the email.", "Please check your spam folder if you didn't receive the email.": "Please check your spam folder if you didn't receive the email.",
"Please contact this instance's Mobilizon admin if you think this is a mistake.": "Please contact this instance's Mobilizon admin if you think this is a mistake.", "Please contact this instance's Mobilizon admin if you think this is a mistake.": "Please contact this instance's Mobilizon admin if you think this is a mistake.",
"Please enter your password to confirm this action.": "Please enter your password to confirm this action.",
"Please make sure the address is correct and that the page hasn't been moved.": "Please make sure the address is correct and that the page hasn't been moved.", "Please make sure the address is correct and that the page hasn't been moved.": "Please make sure the address is correct and that the page hasn't been moved.",
"Please read the full rules": "Please read the full rules", "Please read the full rules": "Please read the full rules",
"Please refresh the page and retry.": "Please refresh the page and retry.", "Please refresh the page and retry.": "Please refresh the page and retry.",
@ -331,9 +341,11 @@
"Street": "Street", "Street": "Street",
"Tentative: Will be confirmed later": "Tentative: Will be confirmed later", "Tentative: Will be confirmed later": "Tentative: Will be confirmed later",
"Terms": "Terms", "Terms": "Terms",
"The account's email address was changed. Check your emails to verify it.": "The account's email address was changed. Check your emails to verify it.",
"The actual number of participants may differ, as this event is hosted on another instance.": "The actual number of participants may differ, as this event is hosted on another instance.", "The actual number of participants may differ, as this event is hosted on another instance.": "The actual number of participants may differ, as this event is hosted on another instance.",
"The content came from another server. Transfer an anonymous copy of the report?": "The content came from another server. Transfer an anonymous copy of the report ?", "The content came from another server. Transfer an anonymous copy of the report?": "The content came from another server. Transfer an anonymous copy of the report ?",
"The current identity doesn't have any permission on this event. You should probably change it.": "The current identity doesn't have any permission on this event. You should probably change it.", "The current identity doesn't have any permission on this event. You should probably change it.": "The current identity doesn't have any permission on this event. You should probably change it.",
"The current password is invalid": "The current password is invalid",
"The draft event has been updated": "The draft event has been updated", "The draft event has been updated": "The draft event has been updated",
"The event has been created as a draft": "The event has been created as a draft", "The event has been created as a draft": "The event has been created as a draft",
"The event has been published": "The event has been published", "The event has been published": "The event has been published",
@ -341,12 +353,17 @@
"The event has been updated": "The event has been updated", "The event has been updated": "The event has been updated",
"The event organizer didn't add any description.": "The event organizer didn't add any description.", "The event organizer didn't add any description.": "The event organizer didn't add any description.",
"The event title will be ellipsed.": "The event title will be ellipsed.", "The event title will be ellipsed.": "The event title will be ellipsed.",
"The new email doesn't seem to be valid": "The new email doesn't seem to be valid",
"The new email must be different": "The new email must be different",
"The new password must be different": "The new password must be different",
"The page you're looking for doesn't exist.": "The page you're looking for doesn't exist.", "The page you're looking for doesn't exist.": "The page you're looking for doesn't exist.",
"The password provided is invalid": "The password provided is invalid",
"The password was successfully changed": "The password was successfully changed", "The password was successfully changed": "The password was successfully changed",
"The report will be sent to the moderators of your instance. You can explain why you report this content below.": "The report will be sent to the moderators of your instance. You can explain why you report this content below.", "The report will be sent to the moderators of your instance. You can explain why you report this content below.": "The report will be sent to the moderators of your instance. You can explain why you report this content below.",
"The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.": "The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.", "The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.": "The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.",
"The {default_terms} will be used. They will be translated in the user's language.": "The {default_terms} will be used. They will be translated in the user's language.", "The {default_terms} will be used. They will be translated in the user's language.": "The {default_terms} will be used. They will be translated in the user's language.",
"There are {participants} participants.": "There are {participants} participants.", "There are {participants} participants.": "There are {participants} participants.",
"There will be no way to recover your data.": "There will be no way to recover your data.",
"These events may interest you": "These events may interest you", "These events may interest you": "These events may interest you",
"This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.", "This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.",
"This email is already registered as participant for this event": "This email is already registered as participant for this event", "This email is already registered as participant for this event": "This email is already registered as participant for this event",
@ -412,9 +429,14 @@
"You need to login.": "You need to login.", "You need to login.": "You need to login.",
"You will be redirected to the original instance": "You will be redirected to the original instance", "You will be redirected to the original instance": "You will be redirected to the original instance",
"You wish to participate to the following event": "You wish to participate to the following event", "You wish to participate to the following event": "You wish to participate to the following event",
"You'll receive a confirmation email.": "You'll receive a confirmation email.",
"Your account has been successfully deleted": "Your account has been successfully deleted",
"Your account has been validated": "Your account has been validated", "Your account has been validated": "Your account has been validated",
"Your account is being validated": "Your account is being validated", "Your account is being validated": "Your account is being validated",
"Your account is nearly ready, {username}": "Your account is nearly ready, {username}", "Your account is nearly ready, {username}": "Your account is nearly ready, {username}",
"Your current email is {email}. You use it to log in.": "Your current email is {email}. You use it to log in.",
"Your email has been changed": "Your email has been changed",
"Your email is being changed": "Your email is being changed",
"Your email is not whitelisted, you can't register.": "Your email is not whitelisted, you can't register.", "Your email is not whitelisted, you can't register.": "Your email is not whitelisted, you can't register.",
"Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.": "Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.", "Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.": "Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.",
"Your federated identity": "Your federated identity", "Your federated identity": "Your federated identity",
@ -446,4 +468,4 @@
"{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.": "{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.", "{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.": "{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.",
"© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks": "© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks", "© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks": "© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks",
"© The OpenStreetMap Contributors": "© The OpenStreetMap Contributors" "© The OpenStreetMap Contributors": "© The OpenStreetMap Contributors"
} }

View File

@ -3,20 +3,21 @@
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Un outil convivial, émancipateur et éthique pour se rassembler, s'organiser et se mobiliser.", "A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Un outil convivial, émancipateur et éthique pour se rassembler, s'organiser et se mobiliser.",
"A validation email was sent to {email}": "Un email de validation a été envoyé à {email}", "A validation email was sent to {email}": "Un email de validation a été envoyé à {email}",
"Abandon edition": "Abandonner la modification", "Abandon edition": "Abandonner la modification",
"About": "À propos",
"About Mobilizon": "À propos de Mobilizon", "About Mobilizon": "À propos de Mobilizon",
"About this event": "À propos de cet évènement", "About this event": "À propos de cet évènement",
"About this instance": "À propos de cette instance", "About this instance": "À propos de cette instance",
"About": "À propos",
"Accepted": "Accepté", "Accepted": "Accepté",
"Add": "Ajouter", "Account settings": "Paramètres du compte",
"Add a note": "Ajouter une note", "Add a note": "Ajouter une note",
"Add an address": "Ajouter une adresse", "Add an address": "Ajouter une adresse",
"Add an instance": "Ajouter une instance", "Add an instance": "Ajouter une instance",
"Add some tags": "Ajouter des tags", "Add some tags": "Ajouter des tags",
"Add to my calendar": "Ajouter à mon agenda", "Add to my calendar": "Ajouter à mon agenda",
"Add": "Ajouter",
"Additional comments": "Commentaires additionnels", "Additional comments": "Commentaires additionnels",
"Admin settings": "Paramètres administrateur",
"Admin settings successfully saved.": "Les paramètres administrateur ont bien été sauvegardés", "Admin settings successfully saved.": "Les paramètres administrateur ont bien été sauvegardés",
"Admin settings": "Paramètres administrateur",
"Administration": "Administration", "Administration": "Administration",
"All the places have already been taken": "Toutes les places ont été prises|Une place est encore disponible|{places} places sont encore disponibles", "All the places have already been taken": "Toutes les places ont été prises|Une place est encore disponible|{places} places sont encore disponibles",
"Allow all comments": "Autoriser tous les commentaires", "Allow all comments": "Autoriser tous les commentaires",
@ -26,6 +27,7 @@
"Anonymous participants will be asked to confirm their participation through e-mail.": "Les participants anonymes devront confirmer leur participation par email.", "Anonymous participants will be asked to confirm their participation through e-mail.": "Les participants anonymes devront confirmer leur participation par email.",
"Anonymous participations": "Participations anonymes", "Anonymous participations": "Participations anonymes",
"Approve": "Approuver", "Approve": "Approuver",
"Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.": "Êtes-vous vraiment certain⋅e de vouloir supprimer votre compte ? Vous allez tout perdre. Identités, paramètres, événements créés, messages et participations disparaîtront pour toujours.",
"Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> ce commentaire ? Cette action ne peut pas être annulée.", "Are you sure you want to <b>delete</b> this comment? This action cannot be undone.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> ce commentaire ? Cette action ne peut pas être annulée.",
"Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> cet évènement ? Cette action n'est pas réversible. Vous voulez peut-être engager la conversation avec le créateur de l'évènement ou bien modifier son évènement à la place.", "Are you sure you want to <b>delete</b> this event? This action cannot be undone. You may want to engage the conversation with the event creator or edit its event instead.": "Êtes-vous certain⋅e de vouloir <b>supprimer</b> cet évènement ? Cette action n'est pas réversible. Vous voulez peut-être engager la conversation avec le créateur de l'évènement ou bien modifier son évènement à la place.",
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Étes-vous certain⋅e de vouloir annuler la création de l'évènement ? Vous allez perdre toutes vos modifications.", "Are you sure you want to cancel the event creation? You'll lose all modifications.": "Étes-vous certain⋅e de vouloir annuler la création de l'évènement ? Vous allez perdre toutes vos modifications.",
@ -36,34 +38,34 @@
"Back to previous page": "Retour à la page précédente", "Back to previous page": "Retour à la page précédente",
"Before you can login, you need to click on the link inside it to validate your account": "Avant que vous puissiez vous enregistrer, vous devez cliquer sur le lien à l'intérieur pour valider votre compte", "Before you can login, you need to click on the link inside it to validate your account": "Avant que vous puissiez vous enregistrer, vous devez cliquer sur le lien à l'intérieur pour valider votre compte",
"By {name}": "Par {name}", "By {name}": "Par {name}",
"Cancel": "Annuler",
"Cancel anonymous participation": "Annuler ma participation anonyme", "Cancel anonymous participation": "Annuler ma participation anonyme",
"Cancel creation": "Annuler la création", "Cancel creation": "Annuler la création",
"Cancel edition": "Annuler la modification", "Cancel edition": "Annuler la modification",
"Cancel my participation request…": "Annuler ma demande de participation…", "Cancel my participation request…": "Annuler ma demande de participation…",
"Cancel my participation…": "Annuler ma participation…", "Cancel my participation…": "Annuler ma participation…",
"Cancel": "Annuler",
"Cancelled: Won't happen": "Annulé : N'aura pas lieu", "Cancelled: Won't happen": "Annulé : N'aura pas lieu",
"Category": "Catégorie", "Category": "Catégorie",
"Change": "Modifier", "Change my email": "Changer mon adresse e-mail",
"Change my identity…": "Changer mon identité…", "Change my identity…": "Changer mon identité…",
"Change my password": "Modifier mon mot de passe", "Change my password": "Modifier mon mot de passe",
"Change password": "Modifier mot de passe", "Change password": "Modifier mot de passe",
"Change": "Modifier",
"Clear": "Effacer", "Clear": "Effacer",
"Click to select": "Cliquez pour sélectionner", "Click to select": "Cliquez pour sélectionner",
"Click to upload": "Cliquez pour uploader", "Click to upload": "Cliquez pour uploader",
"Close": "Fermé",
"Close comments for all (except for admins)": "Fermer les commentaires à tout le monde (excepté les administrateurs)", "Close comments for all (except for admins)": "Fermer les commentaires à tout le monde (excepté les administrateurs)",
"Close": "Fermé",
"Closed": "Fermé", "Closed": "Fermé",
"Comment deleted": "Commentaire supprimé", "Comment deleted": "Commentaire supprimé",
"Comment from @{username} reported": "Commentaire de @{username} signalé", "Comment from @{username} reported": "Commentaire de @{username} signalé",
"Comments": "Commentaires",
"Comments have been closed.": "Les commentaires sont fermés.", "Comments have been closed.": "Les commentaires sont fermés.",
"Comments on the event page": "Commentaires sur la page de l'événement", "Comments on the event page": "Commentaires sur la page de l'événement",
"Comments": "Commentaires",
"Confirm my particpation": "Confirmer ma participation", "Confirm my particpation": "Confirmer ma participation",
"Confirmed: Will happen": "Confirmé : aura lieu", "Confirmed: Will happen": "Confirmé : aura lieu",
"Continue editing": "Continuer la modification", "Continue editing": "Continuer la modification",
"Country": "Pays", "Country": "Pays",
"Create": "Créer",
"Create a new event": "Créer un nouvel évènement", "Create a new event": "Créer un nouvel évènement",
"Create a new group": "Créer un nouveau groupe", "Create a new group": "Créer un nouveau groupe",
"Create a new identity": "Créer une nouvelle identité", "Create a new identity": "Créer une nouvelle identité",
@ -74,27 +76,33 @@
"Create my profile": "Créer mon profil", "Create my profile": "Créer mon profil",
"Create token": "Créer un jeton", "Create token": "Créer un jeton",
"Create, edit or delete events": "Créer, modifier ou supprimer des évènements", "Create, edit or delete events": "Créer, modifier ou supprimer des évènements",
"Create": "Créer",
"Creator": "Créateur", "Creator": "Créateur",
"Current identity has been changed to {identityName} in order to manage this event.": "L'identité actuelle a été changée à {identityName} pour pouvoir gérer cet évènement.", "Current identity has been changed to {identityName} in order to manage this event.": "L'identité actuelle a été changée à {identityName} pour pouvoir gérer cet évènement.",
"Custom": "Custom",
"Custom URL": "URL personnalisée", "Custom URL": "URL personnalisée",
"Custom text": "Texte personnalisé", "Custom text": "Texte personnalisé",
"Custom": "Custom",
"Dashboard": "Tableau de bord", "Dashboard": "Tableau de bord",
"Date": "Date",
"Date and time settings": "Paramètres de date et d'heure", "Date and time settings": "Paramètres de date et d'heure",
"Date parameters": "Paramètres de date", "Date parameters": "Paramètres de date",
"Default": "Default", "Date": "Date",
"Default Mobilizon.org terms": "Conditions d'utilisation par défaut de Mobilizon.org", "Default Mobilizon.org terms": "Conditions d'utilisation par défaut de Mobilizon.org",
"Delete": "Supprimer", "Default": "Default",
"Delete Comment": "Supprimer le commentaire", "Delete Comment": "Supprimer le commentaire",
"Delete Event": "Supprimer l'évènement", "Delete Event": "Supprimer l'évènement",
"Delete account": "Suppression du compte",
"Delete event": "Supprimer un évènement", "Delete event": "Supprimer un évènement",
"Delete everything": "Tout supprimer",
"Delete my account": "Supprimer mon compte",
"Delete this identity": "Supprimer cette identité", "Delete this identity": "Supprimer cette identité",
"Delete your identity": "Supprimer votre identité", "Delete your identity": "Supprimer votre identité",
"Delete {eventTitle}": "Supprimer {eventTitle}", "Delete {eventTitle}": "Supprimer {eventTitle}",
"Delete {preferredUsername}": "Supprimer {preferredUsername}", "Delete {preferredUsername}": "Supprimer {preferredUsername}",
"Delete": "Supprimer",
"Deleting comment": "Suppression du commentaire en cours", "Deleting comment": "Suppression du commentaire en cours",
"Deleting event": "Suppression de l'évènement", "Deleting event": "Suppression de l'évènement",
"Deleting my account will delete all of my identities.": "Supprimer mon compte supprimera toutes mes identités.",
"Deleting your Mobilizon account": "Supprimer votre compte Mobilizon",
"Description": "Description", "Description": "Description",
"Didn't receive the instructions ?": "Vous n'avez pas reçu les instructions ?", "Didn't receive the instructions ?": "Vous n'avez pas reçu les instructions ?",
"Display name": "Nom affiché", "Display name": "Nom affiché",
@ -106,17 +114,18 @@
"Eg: Stockholm, Dance, Chess…": "Par exemple : Lyon, Danse, Bridge…", "Eg: Stockholm, Dance, Chess…": "Par exemple : Lyon, Danse, Bridge…",
"Either on the {instance} instance or on another instance.": "Sur l'instance {instance} ou bien sur une autre instance.", "Either on the {instance} instance or on another instance.": "Sur l'instance {instance} ou bien sur une autre instance.",
"Either the account is already validated, either the validation token is incorrect.": "Soit le compte est déjà validé, soit le jeton de validation est incorrect.", "Either the account is already validated, either the validation token is incorrect.": "Soit le compte est déjà validé, soit le jeton de validation est incorrect.",
"Either the email has already been changed, either the validation token is incorrect.": "Soit l'adresse email a déjà été modifiée, soit le jeton de validation est incorrect.",
"Either the participation has already been validated, either the validation token is incorrect.": "Either the participation has already been validated, either the validation token is incorrect.", "Either the participation has already been validated, either the validation token is incorrect.": "Either the participation has already been validated, either the validation token is incorrect.",
"Email": "Email", "Email": "Email",
"Ends on…": "Se termine le…", "Ends on…": "Se termine le…",
"Enjoy discovering Mobilizon!": "Amusez-vous bien en découvrant Mobilizon !", "Enjoy discovering Mobilizon!": "Amusez-vous bien en découvrant Mobilizon !",
"Enter the link URL": "Entrez l'URL du lien", "Enter the link URL": "Entrez l'URL du lien",
"Enter your own terms. HTML tags allowed. Mobilizon.org's terms are provided as template.": "Entrez vos propres conditions d'utilisations. Les balises HTML sont autorisées. Les conditions d'utilisation par défaut de Mobilizon.org sont fournies comme modèle.", "Enter your own terms. HTML tags allowed. Mobilizon.org's terms are provided as template.": "Entrez vos propres conditions d'utilisations. Les balises HTML sont autorisées. Les conditions d'utilisation par défaut de Mobilizon.org sont fournies comme modèle.",
"Error while changing email": "Erreur lors de la modification de l'adresse email",
"Error while communicating with the server.": "Erreur de communication avec le serveur.", "Error while communicating with the server.": "Erreur de communication avec le serveur.",
"Error while saving report.": "Erreur lors de l'enregistrement du signalement.", "Error while saving report.": "Erreur lors de l'enregistrement du signalement.",
"Error while validating account": "Erreur lors de la validation du compte", "Error while validating account": "Erreur lors de la validation du compte",
"Error while validating participation": "Error lors de la validation de la participation", "Error while validating participation": "Error lors de la validation de la participation",
"Event": "Événement",
"Event already passed": "Événement déjà passé", "Event already passed": "Événement déjà passé",
"Event cancelled": "Événement annulé", "Event cancelled": "Événement annulé",
"Event creation": "Création d'évènement", "Event creation": "Création d'évènement",
@ -127,6 +136,7 @@
"Event to be confirmed": "Événement à confirmer", "Event to be confirmed": "Événement à confirmer",
"Event {eventTitle} deleted": "Événement {eventTitle} supprimé", "Event {eventTitle} deleted": "Événement {eventTitle} supprimé",
"Event {eventTitle} reported": "Événement {eventTitle} signalé", "Event {eventTitle} reported": "Événement {eventTitle} signalé",
"Event": "Événement",
"Events": "Événements", "Events": "Événements",
"Ex: test.mobilizon.org": "Ex : test.mobilizon.org", "Ex: test.mobilizon.org": "Ex : test.mobilizon.org",
"Exclude": "Exclure", "Exclude": "Exclure",
@ -141,8 +151,8 @@
"For instance: London, Taekwondo, Architecture…": "Par exemple : Lyon, Taekwondo, Architecture…", "For instance: London, Taekwondo, Architecture…": "Par exemple : Lyon, Taekwondo, Architecture…",
"Forgot your password ?": "Mot de passe oublié ?", "Forgot your password ?": "Mot de passe oublié ?",
"From a birthday party with friends and family to a march for climate change, right now, our gatherings are <b>trapped inside the tech giants platforms</b>. How can we organize, how can we click “Attend,” without <b>providing private data</b> to Facebook or <b>locking ourselves up</b> inside MeetUp?": "De lanniversaire entre ami·e·s à une marche pour le climat, aujourdhui, les bonnes raisons de se rassembler sont <b>captées par les géants du web</b>. Comment sorganiser, comment cliquer sur «je participe» sans <b>livrer des données intimes</b> à Facebook ou<b> senfermer</b> dans MeetUp?", "From a birthday party with friends and family to a march for climate change, right now, our gatherings are <b>trapped inside the tech giants platforms</b>. How can we organize, how can we click “Attend,” without <b>providing private data</b> to Facebook or <b>locking ourselves up</b> inside MeetUp?": "De lanniversaire entre ami·e·s à une marche pour le climat, aujourdhui, les bonnes raisons de se rassembler sont <b>captées par les géants du web</b>. Comment sorganiser, comment cliquer sur «je participe» sans <b>livrer des données intimes</b> à Facebook ou<b> senfermer</b> dans MeetUp?",
"From the {startDate} at {startTime} to the {endDate}": "Du {startDate} à {startTime} jusqu'au {endDate}",
"From the {startDate} at {startTime} to the {endDate} at {endTime}": "Du {startDate} à {startTime} au {endDate} à {endTime}", "From the {startDate} at {startTime} to the {endDate} at {endTime}": "Du {startDate} à {startTime} au {endDate} à {endTime}",
"From the {startDate} at {startTime} to the {endDate}": "Du {startDate} à {startTime} jusqu'au {endDate}",
"From the {startDate} to the {endDate}": "Du {startDate} au {endDate}", "From the {startDate} to the {endDate}": "Du {startDate} au {endDate}",
"Gather ⋅ Organize ⋅ Mobilize": "Rassembler ⋅ Organiser ⋅ Mobiliser", "Gather ⋅ Organize ⋅ Mobilize": "Rassembler ⋅ Organiser ⋅ Mobiliser",
"General information": "Informations générales", "General information": "Informations générales",
@ -173,15 +183,15 @@
"Installing Mobilizon will allow communities to free themselves from the services of tech giants by creating <b>their own event platform</b>.": "Installer Mobilizon permettra à des collectifs de sémanciper des outils des géants du web en créant <b>leur propre plateforme dévènements</b>.", "Installing Mobilizon will allow communities to free themselves from the services of tech giants by creating <b>their own event platform</b>.": "Installer Mobilizon permettra à des collectifs de sémanciper des outils des géants du web en créant <b>leur propre plateforme dévènements</b>.",
"Instance Description": "Description de l'instance ", "Instance Description": "Description de l'instance ",
"Instance Name": "Nom de l'instance", "Instance Name": "Nom de l'instance",
"Instance Terms": "Conditions générales de l'instance",
"Instance Terms Source": "Source des conditions d'utilisation de l'instance", "Instance Terms Source": "Source des conditions d'utilisation de l'instance",
"Instance Terms URL": "URL des conditions générales de l'instance", "Instance Terms URL": "URL des conditions générales de l'instance",
"Instance Terms": "Conditions générales de l'instance",
"Instances": "Instances", "Instances": "Instances",
"Join {instance}, a Mobilizon instance": "Rejoignez {instance}, une instance Mobilizon", "Join {instance}, a Mobilizon instance": "Rejoignez {instance}, une instance Mobilizon",
"Last published event": "Dernier évènement publié", "Last published event": "Dernier évènement publié",
"Last week": "La semaine dernière", "Last week": "La semaine dernière",
"Learn more": "En apprendre plus",
"Learn more about Mobilizon": "En apprendre plus à propos de Mobilizon", "Learn more about Mobilizon": "En apprendre plus à propos de Mobilizon",
"Learn more": "En apprendre plus",
"Leave event": "Annuler ma participation à l'évènement", "Leave event": "Annuler ma participation à l'évènement",
"Leaving event \"{title}\"": "Annuler ma participation à l'évènement", "Leaving event \"{title}\"": "Annuler ma participation à l'évènement",
"Let's create a new common": "Créons un nouveau Common", "Let's create a new common": "Créons un nouveau Common",
@ -191,9 +201,9 @@
"Locality": "Commune", "Locality": "Commune",
"Log in": "Se connecter", "Log in": "Se connecter",
"Log out": "Se déconnecter", "Log out": "Se déconnecter",
"Login": "Se connecter",
"Login on Mobilizon!": "Se connecter sur Mobilizon !", "Login on Mobilizon!": "Se connecter sur Mobilizon !",
"Login on {instance}": "Se connecter sur {instance}", "Login on {instance}": "Se connecter sur {instance}",
"Login": "Se connecter",
"Manage participations": "Gérer les participations", "Manage participations": "Gérer les participations",
"Mark as resolved": "Marquer comme résolu", "Mark as resolved": "Marquer comme résolu",
"Members": "Membres", "Members": "Membres",
@ -206,6 +216,7 @@
"My events": "Mes évènements", "My events": "Mes évènements",
"My identities": "Mes identités", "My identities": "Mes identités",
"Name": "Nom", "Name": "Nom",
"New email": "Nouvelle adresse e-mail",
"New note": "Nouvelle note", "New note": "Nouvelle note",
"New password": "Nouveau mot de passe", "New password": "Nouveau mot de passe",
"No actors found": "Aucun acteur trouvé", "No actors found": "Aucun acteur trouvé",
@ -229,18 +240,18 @@
"Number of places": "Nombre de places", "Number of places": "Nombre de places",
"OK": "OK", "OK": "OK",
"Old password": "Ancien mot de passe", "Old password": "Ancien mot de passe",
"On {date}": "Le {date}",
"On {date} ending at {endTime}": "Le {date}, se terminant à {endTime}", "On {date} ending at {endTime}": "Le {date}, se terminant à {endTime}",
"On {date} from {startTime} to {endTime}": "Le {date} de {startTime} à {endTime}", "On {date} from {startTime} to {endTime}": "Le {date} de {startTime} à {endTime}",
"On {date} starting at {startTime}": "Le {date} à partir de {startTime}", "On {date} starting at {startTime}": "Le {date} à partir de {startTime}",
"On {date}": "Le {date}",
"One person is going": "Personne n'y va | Une personne y va | {approved} personnes y vont", "One person is going": "Personne n'y va | Une personne y va | {approved} personnes y vont",
"Only accessible through link and search (private)": "Uniquement accessibles par lien et la recherche (privé)", "Only accessible through link and search (private)": "Uniquement accessibles par lien et la recherche (privé)",
"Only alphanumeric characters and underscores are supported.": "Seuls les caractères alphanumériques et les tirets bas sont acceptés.", "Only alphanumeric characters and underscores are supported.": "Seuls les caractères alphanumériques et les tirets bas sont acceptés.",
"Open": "Ouvert", "Open": "Ouvert",
"Opened reports": "Signalements ouverts", "Opened reports": "Signalements ouverts",
"Or": "Ou", "Or": "Ou",
"Organized": "Organisés",
"Organized by {name}": "Organisé par {name}", "Organized by {name}": "Organisé par {name}",
"Organized": "Organisés",
"Organizer": "Organisateur", "Organizer": "Organisateur",
"Other software may also support this.": "D'autres logiciels peuvent également supporter cette fonctionnalité.", "Other software may also support this.": "D'autres logiciels peuvent également supporter cette fonctionnalité.",
"Otherwise this identity will just be removed from the group administrators.": "Sinon cette identité sera juste supprimée des administrateurs du groupe.", "Otherwise this identity will just be removed from the group administrators.": "Sinon cette identité sera juste supprimée des administrateurs du groupe.",
@ -249,19 +260,20 @@
"Participant already was rejected.": "Le participant a déjà été refusé.", "Participant already was rejected.": "Le participant a déjà été refusé.",
"Participant has already been approved as participant.": "Le participant a déjà été approuvé en tant que participant.", "Participant has already been approved as participant.": "Le participant a déjà été approuvé en tant que participant.",
"Participants": "Participants", "Participants": "Participants",
"Participate": "Participer",
"Participate using your email address": "Participer en utilisant votre adresse email", "Participate using your email address": "Participer en utilisant votre adresse email",
"Participate": "Participer",
"Participation approval": "Validation des participations", "Participation approval": "Validation des participations",
"Participation requested!": "Participation demandée !", "Participation requested!": "Participation demandée !",
"Password": "Mot de passe",
"Password (confirmation)": "Mot de passe (confirmation)", "Password (confirmation)": "Mot de passe (confirmation)",
"Password change": "Changement de mot de passe", "Password change": "Changement de mot de passe",
"Password reset": "Réinitialisation du mot de passe", "Password reset": "Réinitialisation du mot de passe",
"Password": "Mot de passe",
"Past events": "Événements passés", "Past events": "Événements passés",
"Pending": "En attente", "Pending": "En attente",
"Pick an identity": "Choisissez une identité", "Pick an identity": "Choisissez une identité",
"Please check your spam folder if you didn't receive the email.": "Merci de vérifier votre dossier des indésirables si vous n'avez pas reçu l'email.", "Please check your spam folder if you didn't receive the email.": "Merci de vérifier votre dossier des indésirables si vous n'avez pas reçu l'email.",
"Please contact this instance's Mobilizon admin if you think this is a mistake.": "Veuillez contacter l'administrateur de cette instance Mobilizon si vous pensez quil sagit dune erreur.", "Please contact this instance's Mobilizon admin if you think this is a mistake.": "Veuillez contacter l'administrateur de cette instance Mobilizon si vous pensez quil sagit dune erreur.",
"Please enter your password to confirm this action.": "Merci d'entrer votre mot de passe pour confirmer cette action.",
"Please make sure the address is correct and that the page hasn't been moved.": "Assurezvous que ladresse est correcte et que la page na pas été déplacée.", "Please make sure the address is correct and that the page hasn't been moved.": "Assurezvous que ladresse est correcte et que la page na pas été déplacée.",
"Please read the full rules": "Merci de lire les règles complètes", "Please read the full rules": "Merci de lire les règles complètes",
"Please refresh the page and retry.": "Merci de rafraîchir la page puis réessayer.", "Please refresh the page and retry.": "Merci de rafraîchir la page puis réessayer.",
@ -283,37 +295,37 @@
"Read Framasofts statement of intent on the Framablog": "Lire la note dintention de Framasoft sur le Framablog", "Read Framasofts statement of intent on the Framablog": "Lire la note dintention de Framasoft sur le Framablog",
"Redirecting to event…": "Redirection vers l'événement…", "Redirecting to event…": "Redirection vers l'événement…",
"Region": "Région", "Region": "Région",
"Register": "S'inscrire",
"Register an account on Mobilizon!": "S'inscrire sur Mobilizon !", "Register an account on Mobilizon!": "S'inscrire sur Mobilizon !",
"Register for an event by choosing one of your identities": "S'inscrire à un évènement en choisissant une de vos identités", "Register for an event by choosing one of your identities": "S'inscrire à un évènement en choisissant une de vos identités",
"Register": "S'inscrire",
"Registration is allowed, anyone can register.": "Les inscriptions sont autorisées, n'importe qui peut s'inscrire.", "Registration is allowed, anyone can register.": "Les inscriptions sont autorisées, n'importe qui peut s'inscrire.",
"Registration is closed.": "Les inscriptions sont fermées.", "Registration is closed.": "Les inscriptions sont fermées.",
"Registration is currently closed.": "Les inscriptions sont actuellement fermées.", "Registration is currently closed.": "Les inscriptions sont actuellement fermées.",
"Registrations are restricted by whitelisting.": "Les inscriptions sont restreintes par liste blanche.", "Registrations are restricted by whitelisting.": "Les inscriptions sont restreintes par liste blanche.",
"Reject": "Rejeter", "Reject": "Rejeter",
"Rejected": "Rejetés",
"Rejected participations": "Participations rejetées", "Rejected participations": "Participations rejetées",
"Rejected": "Rejetés",
"Reopen": "Réouvrir", "Reopen": "Réouvrir",
"Reply": "Répondre", "Reply": "Répondre",
"Report": "Signalement",
"Report this comment": "Signaler ce commentaire", "Report this comment": "Signaler ce commentaire",
"Report this event": "Signaler cet évènement", "Report this event": "Signaler cet évènement",
"Reported": "Signalée", "Report": "Signalement",
"Reported by": "Signalée par",
"Reported by someone on {domain}": "Signalé par quelqu'un depuis {domain}", "Reported by someone on {domain}": "Signalé par quelqu'un depuis {domain}",
"Reported by {reporter}": "Signalé par {reporter}", "Reported by {reporter}": "Signalé par {reporter}",
"Reported by": "Signalée par",
"Reported identity": "Identité signalée", "Reported identity": "Identité signalée",
"Reported": "Signalée",
"Reports": "Signalements", "Reports": "Signalements",
"Requests": "Requêtes", "Requests": "Requêtes",
"Resend confirmation email": "Envoyer à nouveau l'email de confirmation", "Resend confirmation email": "Envoyer à nouveau l'email de confirmation",
"Reset my password": "Réinitialiser mon mot de passe", "Reset my password": "Réinitialiser mon mot de passe",
"Resolved": "Résolu", "Resolved": "Résolu",
"Resource provided is not an URL": "La ressource fournie n'est pas une URL", "Resource provided is not an URL": "La ressource fournie n'est pas une URL",
"Save": "Enregistrer",
"Save draft": "Enregistrer le brouillon", "Save draft": "Enregistrer le brouillon",
"Search": "Rechercher", "Save": "Enregistrer",
"Search events, groups, etc.": "Rechercher des évènements, des groupes, etc.", "Search events, groups, etc.": "Rechercher des évènements, des groupes, etc.",
"Search results: \"{search}\"": "Résultats de recherche : « {search} »", "Search results: \"{search}\"": "Résultats de recherche : « {search} »",
"Search": "Rechercher",
"Searching…": "Recherche en cours…", "Searching…": "Recherche en cours…",
"Send email": "Envoyer un email", "Send email": "Envoyer un email",
"Send me an email to reset my password": "Envoyez-moi un email pour réinitialiser mon mot de passe", "Send me an email to reset my password": "Envoyez-moi un email pour réinitialiser mon mot de passe",
@ -333,22 +345,29 @@
"Street": "Rue", "Street": "Rue",
"Tentative: Will be confirmed later": "Provisoire : sera confirmé plus tard", "Tentative: Will be confirmed later": "Provisoire : sera confirmé plus tard",
"Terms": "Conditions d'utilisation", "Terms": "Conditions d'utilisation",
"The account's email address was changed. Check your emails to verify it.": "L'adresse email du compte a été modifiée. Vérifiez vos emails pour confirmer le changement.",
"The actual number of participants may differ, as this event is hosted on another instance.": "Le nombre réel de participants peut être différent, car cet événement provient d'une autre instance.", "The actual number of participants may differ, as this event is hosted on another instance.": "Le nombre réel de participants peut être différent, car cet événement provient d'une autre instance.",
"The content came from another server. Transfer an anonymous copy of the report?": "Le contenu provient d'une autre instance. Transférer une copie anonyme du signalement ?", "The content came from another server. Transfer an anonymous copy of the report?": "Le contenu provient d'une autre instance. Transférer une copie anonyme du signalement ?",
"The current identity doesn't have any permission on this event. You should probably change it.": "L'identité actuelle n'a pas de permissions sur cet évènement. Vous devriez probablement en changer.", "The current identity doesn't have any permission on this event. You should probably change it.": "L'identité actuelle n'a pas de permissions sur cet évènement. Vous devriez probablement en changer.",
"The current password is invalid": "Le mot de passe actuel est invalide",
"The draft event has been updated": "L'évènement brouillon a été mis à jour", "The draft event has been updated": "L'évènement brouillon a été mis à jour",
"The event has been created as a draft": "L'évènement a été créé en tant que brouillon", "The event has been created as a draft": "L'évènement a été créé en tant que brouillon",
"The event has been published": "L'évènement a été publié", "The event has been published": "L'évènement a été publié",
"The event has been updated": "L'évènement a été mis à jour",
"The event has been updated and published": "L'évènement a été mis à jour et publié", "The event has been updated and published": "L'évènement a été mis à jour et publié",
"The event has been updated": "L'évènement a été mis à jour",
"The event organizer didn't add any description.": "L'organisateur de l'évènement n'a pas ajouté de description.", "The event organizer didn't add any description.": "L'organisateur de l'évènement n'a pas ajouté de description.",
"The event title will be ellipsed.": "Le titre de l'évènement sera ellipsé.", "The event title will be ellipsed.": "Le titre de l'évènement sera ellipsé.",
"The new email doesn't seem to be valid": "La nouvelle adresse email ne semble pas être valide",
"The new email must be different": "La nouvelle adresse email doit être différente",
"The new password must be different": "Le nouveau mot de passe doit être différent",
"The page you're looking for doesn't exist.": "La page que vous recherchez n'existe pas.", "The page you're looking for doesn't exist.": "La page que vous recherchez n'existe pas.",
"The password provided is invalid": "Le mot de passe fourni est invalide",
"The password was successfully changed": "Le mot de passe a été changé avec succès", "The password was successfully changed": "Le mot de passe a été changé avec succès",
"The report will be sent to the moderators of your instance. You can explain why you report this content below.": "Le signalement sera envoyé aux modérateur⋅ices de votre instance. Vous pouvez expliquer pourquoi vous signalez ce contenu ci-dessous.", "The report will be sent to the moderators of your instance. You can explain why you report this content below.": "Le signalement sera envoyé aux modérateur⋅ices de votre instance. Vous pouvez expliquer pourquoi vous signalez ce contenu ci-dessous.",
"The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.": "Le compte utilisateur avec lequel vous essayez de vous connectez n'a pas été confirmé. Vérifiez la boite de réception de votre adresse email et éventuellement le dossier des messages indésirables.", "The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.": "Le compte utilisateur avec lequel vous essayez de vous connectez n'a pas été confirmé. Vérifiez la boite de réception de votre adresse email et éventuellement le dossier des messages indésirables.",
"The {default_terms} will be used. They will be translated in the user's language.": "Les {default_terms} seront utilisées. Elles seront traduites dans la langue de l'utilisateur⋅ice.", "The {default_terms} will be used. They will be translated in the user's language.": "Les {default_terms} seront utilisées. Elles seront traduites dans la langue de l'utilisateur⋅ice.",
"There are {participants} participants.": "Il n'y a qu'un⋅e participant⋅e. | Il y a {participants} participants.", "There are {participants} participants.": "Il n'y a qu'un⋅e participant⋅e. | Il y a {participants} participants.",
"There will be no way to recover your data.": "Il n'y aura aucun moyen de récupérer vos données.",
"These events may interest you": "Ces évènements peuvent vous intéresser", "These events may interest you": "Ces évènements peuvent vous intéresser",
"This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Cette instance Mobilizon et l'organisateur⋅ice de l'événement autorise les participations anonymes, mais requiert une validation à travers une confirmation par email.", "This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Cette instance Mobilizon et l'organisateur⋅ice de l'événement autorise les participations anonymes, mais requiert une validation à travers une confirmation par email.",
"This email is already registered as participant for this event": "Cet email est déjà enregistré comme participant pour cet événement", "This email is already registered as participant for this event": "Cet email est déjà enregistré comme participant pour cet événement",
@ -367,9 +386,9 @@
"URL": "URL", "URL": "URL",
"Unfortunately, this instance isn't opened to registrations": "Malheureusement, cette instance n'est pas ouverte aux inscriptions", "Unfortunately, this instance isn't opened to registrations": "Malheureusement, cette instance n'est pas ouverte aux inscriptions",
"Unfortunately, your participation request was rejected by the organizers.": "Malheureusement, votre demande de participation a été refusée par les organisateur⋅ices.", "Unfortunately, your participation request was rejected by the organizers.": "Malheureusement, votre demande de participation a été refusée par les organisateur⋅ices.",
"Unknown": "Inconnu",
"Unknown actor": "Acteur inconnu", "Unknown actor": "Acteur inconnu",
"Unknown error.": "Erreur inconnue.", "Unknown error.": "Erreur inconnue.",
"Unknown": "Inconnu",
"Unsaved changes": "Modifications non enregistrées", "Unsaved changes": "Modifications non enregistrées",
"Upcoming": "À venir", "Upcoming": "À venir",
"Update event {name}": "Mettre à jour l'évènement {name}", "Update event {name}": "Mettre à jour l'évènement {name}",
@ -400,8 +419,8 @@
"You and one other person are going to this event": "Vous êtes le ou la seule à vous rendre à cet évènement | Vous et une autre personne vous rendez à cet évènement | Vous et {approved} autres personnes vous rendez à cet évènement.", "You and one other person are going to this event": "Vous êtes le ou la seule à vous rendre à cet évènement | Vous et une autre personne vous rendez à cet évènement | Vous et {approved} autres personnes vous rendez à cet évènement.",
"You are already a participant of this event.": "Vous participez déjà à cet évènement.", "You are already a participant of this event.": "Vous participez déjà à cet évènement.",
"You are already logged-in.": "Vous êtes déjà connecté.", "You are already logged-in.": "Vous êtes déjà connecté.",
"You are participating in this event anonymously": "Vous participez à cet événement anonymement",
"You are participating in this event anonymously but didn't confirm participation": "Vous participez à cet événement anonymement mais vous n'avez pas confirmé votre participation", "You are participating in this event anonymously but didn't confirm participation": "Vous participez à cet événement anonymement mais vous n'avez pas confirmé votre participation",
"You are participating in this event anonymously": "Vous participez à cet événement anonymement",
"You can add tags by hitting the Enter key or by adding a comma": "Vous pouvez ajouter des tags en appuyant sur la touche Entrée ou bien en ajoutant une virgule", "You can add tags by hitting the Enter key or by adding a comma": "Vous pouvez ajouter des tags en appuyant sur la touche Entrée ou bien en ajoutant une virgule",
"You can try another search term or drag and drop the marker on the map": "Vous pouvez essayer avec d'autres termes de recherche ou bien glisser et déposer le marqueur sur la carte", "You can try another search term or drag and drop the marker on the map": "Vous pouvez essayer avec d'autres termes de recherche ou bien glisser et déposer le marqueur sur la carte",
"You can't remove your last identity.": "Vous ne pouvez pas supprimer votre dernière identité.", "You can't remove your last identity.": "Vous ne pouvez pas supprimer votre dernière identité.",
@ -415,13 +434,18 @@
"You need to login.": "Vous devez vous connecter.", "You need to login.": "Vous devez vous connecter.",
"You will be redirected to the original instance": "Vous allez être redirigé⋅e vers l'instance d'origine", "You will be redirected to the original instance": "Vous allez être redirigé⋅e vers l'instance d'origine",
"You wish to participate to the following event": "Vous souhaitez participer à l'événement suivant", "You wish to participate to the following event": "Vous souhaitez participer à l'événement suivant",
"You'll receive a confirmation email.": "Vous recevrez un email de confirmation.",
"Your account has been successfully deleted": "Votre compte a été supprimé avec succès",
"Your account has been validated": "Votre compte a été validé", "Your account has been validated": "Votre compte a été validé",
"Your account is being validated": "Votre compte est en cours de validation", "Your account is being validated": "Votre compte est en cours de validation",
"Your account is nearly ready, {username}": "Votre compte est presque prêt, {username}", "Your account is nearly ready, {username}": "Votre compte est presque prêt, {username}",
"Your current email is {email}. You use it to log in.": "Votre adresse e-mail actuelle est {email}. Vous l'utilisez pour vous connecter.",
"Your email has been changed": "Votre adresse email a bien été modifiée",
"Your email is being changed": "Votre adresse email est en train d'être modifiée",
"Your email is not whitelisted, you can't register.": "Votre email n'est pas sur la liste blanche, vous ne pouvez pas vous inscrire.", "Your email is not whitelisted, you can't register.": "Votre email n'est pas sur la liste blanche, vous ne pouvez pas vous inscrire.",
"Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.": "Votre email sera uniquement utilisé pour confirmer que vous êtes bien une personne réelle et vous envoyer des éventuelles mises à jour pour cet événement. Il ne sera PAS transmis à d'autres instances ou à l'organisateur de l'événement.", "Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.": "Votre email sera uniquement utilisé pour confirmer que vous êtes bien une personne réelle et vous envoyer des éventuelles mises à jour pour cet événement. Il ne sera PAS transmis à d'autres instances ou à l'organisateur de l'événement.",
"Your federated identity": "Votre identité fédérée",
"Your federated identity profile@instance": "Votre identité fédérée profil@instance", "Your federated identity profile@instance": "Votre identité fédérée profil@instance",
"Your federated identity": "Votre identité fédérée",
"Your local administrator resumed its policy:": "Votre administrateur local a résumé sa politique ainsi :", "Your local administrator resumed its policy:": "Votre administrateur local a résumé sa politique ainsi :",
"Your participation has been confirmed": "Votre participation a été confirmée", "Your participation has been confirmed": "Votre participation a été confirmée",
"Your participation has been rejected": "Votre participation a été rejettée", "Your participation has been rejected": "Votre participation a été rejettée",
@ -450,4 +474,4 @@
"{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.": "{license} garantit {respect} des personnes qui l'utiliseront. Puisque {source}, il est publiquement auditable, ce qui garantit sa transparence.", "{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.": "{license} garantit {respect} des personnes qui l'utiliseront. Puisque {source}, il est publiquement auditable, ce qui garantit sa transparence.",
"© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks": "© Les contributeurs de Mobilizon {date} - Fait avec Elixir, Phoenix, VueJS & et de l'amour et des semaines", "© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks": "© Les contributeurs de Mobilizon {date} - Fait avec Elixir, Phoenix, VueJS & et de l'amour et des semaines",
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap" "© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap"
} }

View File

@ -7,7 +7,8 @@ import SendPasswordReset from '@/views/User/SendPasswordReset.vue';
import PasswordReset from '@/views/User/PasswordReset.vue'; import PasswordReset from '@/views/User/PasswordReset.vue';
import { beforeRegisterGuard } from '@/router/guards/register-guard'; import { beforeRegisterGuard } from '@/router/guards/register-guard';
import { RouteConfig } from 'vue-router'; import { RouteConfig } from 'vue-router';
import PasswordChange from '@/views/User/PasswordChange.vue'; import AccountSettings from '@/views/User/AccountSettings.vue';
import EmailValidate from '@/views/User/EmailValidate.vue';
export enum UserRouteName { export enum UserRouteName {
REGISTER = 'Register', REGISTER = 'Register',
@ -17,7 +18,7 @@ export enum UserRouteName {
PASSWORD_RESET = 'PasswordReset', PASSWORD_RESET = 'PasswordReset',
VALIDATE = 'Validate', VALIDATE = 'Validate',
LOGIN = 'Login', LOGIN = 'Login',
PASSWORD_CHANGE = 'PasswordChange', ACCOUNT_SETTINGS = 'ACCOUNT_SETTINGS',
} }
export const userRoutes: RouteConfig[] = [ export const userRoutes: RouteConfig[] = [
@ -58,6 +59,13 @@ export const userRoutes: RouteConfig[] = [
meta: { requiresAuth: false }, meta: { requiresAuth: false },
props: true, props: true,
}, },
{
path: '/validate/email/:token',
name: UserRouteName.VALIDATE,
component: EmailValidate,
props: true,
meta: { requiresAuth: false },
},
{ {
path: '/validate/:token', path: '/validate/:token',
name: UserRouteName.VALIDATE, name: UserRouteName.VALIDATE,
@ -73,9 +81,9 @@ export const userRoutes: RouteConfig[] = [
meta: { requiredAuth: false }, meta: { requiredAuth: false },
}, },
{ {
path: '/my-account/password', path: '/my-account/settings',
name: UserRouteName.PASSWORD_CHANGE, name: UserRouteName.ACCOUNT_SETTINGS,
component: PasswordChange, component: AccountSettings,
meta: { requiredAuth: true }, meta: { requiredAuth: true },
}, },
]; ];

View File

@ -18,7 +18,7 @@
<div class="identities column is-4"> <div class="identities column is-4">
<identities :currentIdentityName="currentIdentityName" /> <identities :currentIdentityName="currentIdentityName" />
<div class="buttons"> <div class="buttons">
<b-button tag="router-link" type="is-secondary" :to="{ name: RouteName.PASSWORD_CHANGE }">{{ $t('Change password') }}</b-button> <b-button tag="router-link" type="is-secondary" :to="{ name: RouteName.ACCOUNT_SETTINGS }">{{ $t('Account settings') }}</b-button>
</div> </div>
</div> </div>
<div class="column is-8"> <div class="column is-8">

View File

@ -0,0 +1,279 @@
<template>
<section class="section container">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.UPDATE_IDENTITY }">{{ $t('My account') }}</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.ACCOUNT_SETTINGS }" aria-current="page">{{ $t('Account settings') }}</router-link></li>
</ul>
</nav>
<div class="setting-title">
<h2>{{ $t('Email') }}</h2>
</div>
<i18n tag="p" class="content" v-if="loggedUser" path="Your current email is {email}. You use it to log in.">
<b slot="email">{{ loggedUser.email }}</b>
</i18n>
<b-notification
type="is-danger"
has-icon
aria-close-label="Close notification"
role="alert"
:key="error"
v-for="error in changeEmailErrors"
>
{{ error }}
</b-notification>
<form @submit.prevent="resetEmailAction" ref="emailForm" class="form">
<b-field :label="$t('New email')">
<b-input
aria-required="true"
required
type="email"
v-model="newEmail"
/>
</b-field>
<p class="help">{{ $t("You'll receive a confirmation email.") }}</p>
<b-field :label="$t('Password')">
<b-input
aria-required="true"
required
type="password"
password-reveal
minlength="6"
v-model="passwordForEmailChange"
/>
</b-field>
<button class="button is-primary" :disabled="!($refs.emailForm && $refs.emailForm.checkValidity())">
{{ $t('Change my email') }}
</button>
</form>
<div class="setting-title">
<h2>{{ $t('Password') }}</h2>
</div>
<b-notification
type="is-danger"
has-icon
aria-close-label="Close notification"
role="alert"
:key="error"
v-for="error in changePasswordErrors"
>
{{ error }}
</b-notification>
<form @submit.prevent="resetPasswordAction" ref="passwordForm" class="form">
<b-field :label="$t('Old password')">
<b-input
aria-required="true"
required
type="password"
password-reveal
minlength="6"
v-model="oldPassword"
/>
</b-field>
<b-field :label="$t('New password')">
<b-input
aria-required="true"
required
type="password"
password-reveal
minlength="6"
v-model="newPassword"
/>
</b-field>
<button class="button is-primary" :disabled="!($refs.passwordForm && $refs.passwordForm.checkValidity())">
{{ $t('Change my password') }}
</button>
</form>
<div class="setting-title">
<h2>{{ $t('Delete account') }}</h2>
</div>
<p class="content">{{ $t('Deleting my account will delete all of my identities.')}}</p>
<b-button @click="openDeleteAccountModal" type="is-danger">{{ $t('Delete my account') }}</b-button>
<b-modal :active.sync="isDeleteAccountModalActive"
has-modal-card full-screen :can-cancel="false">
<section class="hero is-primary is-fullheight">
<div class="hero-body has-text-centered">
<div class="container">
<div class="columns">
<div class="column is-one-third-desktop is-offset-one-third-desktop">
<h1 class="title">
{{ $t('Deleting your Mobilizon account') }}
</h1>
<p class="content">
{{ $t("Are you really sure you want to delete your whole account? You'll lose everything. Identities, settings, events created, messages and participations will be gone forever.") }}
<br>
<b>{{ $t('There will be no way to recover your data.') }}</b>
</p>
<p class="content">{{ $t('Please enter your password to confirm this action.')}}</p>
<form @submit.prevent="deleteAccount">
<b-field>
<b-input type="password" v-model="passwordForAccountDeletion" password-reveal icon="lock" :placeholder="$t('Password')"/>
</b-field>
<b-button native-type="submit" type="is-danger" size="is-large">{{ $t('Delete everything') }}</b-button>
</form>
<div class="cancel-button">
<b-button type="is-light" @click="isDeleteAccountModalActive = false">{{ $t('Cancel') }}</b-button>
</div>
</div>
</div>
</div>
</div>
</section>
</b-modal>
</section>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { CHANGE_EMAIL, CHANGE_PASSWORD, DELETE_ACCOUNT, LOGGED_USER } from '@/graphql/user';
import { RouteName } from '@/router';
import { Refs } from '@/shims-vue';
import { ICurrentUser } from '@/types/current-user.model';
import { logout } from '@/utils/auth';
@Component({
apollo: {
loggedUser: LOGGED_USER,
},
})
export default class AccountSettings extends Vue {
$refs!: Refs<{
passwordForm: HTMLElement,
}>;
loggedUser!: ICurrentUser;
passwordForEmailChange: string = '';
newEmail: string = '';
changeEmailErrors: string[] = [];
oldPassword: string = '';
newPassword: string = '';
changePasswordErrors: string[] = [];
isDeleteAccountModalActive: boolean = false;
passwordForAccountDeletion: string = '';
RouteName = RouteName;
async resetEmailAction() {
this.changeEmailErrors = [];
try {
await this.$apollo.mutate({
mutation: CHANGE_EMAIL,
variables: {
email: this.newEmail,
password: this.passwordForEmailChange,
},
});
this.$notifier.info(this.$t("The account's email address was changed. Check your emails to verify it.") as string);
this.newEmail = '';
this.passwordForEmailChange = '';
} catch (err) {
this.handleErrors('email', err);
}
}
async resetPasswordAction() {
this.changePasswordErrors = [];
try {
await this.$apollo.mutate({
mutation: CHANGE_PASSWORD,
variables: {
oldPassword: this.oldPassword,
newPassword: this.newPassword,
},
});
this.$notifier.success(this.$t('The password was successfully changed') as string);
} catch (err) {
this.handleErrors('password', err);
}
}
protected async openDeleteAccountModal() {
this.passwordForAccountDeletion = '';
this.isDeleteAccountModalActive = true;
}
async deleteAccount() {
try {
await this.$apollo.mutate({
mutation: DELETE_ACCOUNT,
variables: {
password: this.passwordForAccountDeletion,
},
});
await logout(this.$apollo.provider.defaultClient);
this.$buefy.notification.open({
message: this.$t('Your account has been successfully deleted') as string,
type: 'is-success',
position: 'is-bottom-right',
duration: 5000,
});
return await this.$router.push({ name: RouteName.HOME });
} catch (err) {
this.handleErrors('delete', err);
}
}
private handleErrors(type: string, err: any) {
console.error(err);
if (err.graphQLErrors !== undefined) {
err.graphQLErrors.forEach(({ message }) => {
switch (type) {
case 'email':
this.changeEmailErrors.push(this.convertMessage(message) as string);
break;
case 'password':
this.changePasswordErrors.push(this.convertMessage(message) as string);
break;
}
});
}
}
private convertMessage(message: string) {
switch (message) {
case 'The password provided is invalid':
return this.$t('The password provided is invalid');
case 'The new email must be different':
return this.$t('The new email must be different');
case "The new email doesn't seem to be valid":
return this.$t("The new email doesn't seem to be valid");
case 'The current password is invalid':
return this.$t('The current password is invalid');
case 'The new password must be different':
return this.$t('The new password must be different');
}
}
}
</script>
<style lang="scss" scoped>
@import "@/variables.scss";
.setting-title {
margin-top: 3rem;
h2 {
display: inline;
background: $secondary;
padding: 2px 7.5px;
text-transform: uppercase;
font-size: 1.25rem;
}
}
.cancel-button {
margin-top: 2rem;
}
/deep/ .modal .modal-background {
background-color: initial;
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<section class="section container">
<h1 class="title" v-if="loading">
{{ $t('Your email is being changed') }}
</h1>
<div v-else>
<div v-if="failed">
<b-message :title="$t('Error while changing email')" type="is-danger">
{{ $t('Either the email has already been changed, either the validation token is incorrect.') }}
</b-message>
</div>
<h1 class="title" v-else>
{{ $t('Your email has been changed') }}
</h1>
</div>
</section>
</template>
<script lang="ts">
import { VALIDATE_EMAIL } from '@/graphql/user';
import { Component, Prop, Vue } from 'vue-property-decorator';
import { RouteName } from '@/router';
@Component
export default class Validate extends Vue {
@Prop({ type: String, required: true }) token!: string;
loading = true;
failed = false;
async created() {
await this.validateAction();
}
async validateAction() {
try {
await this.$apollo.mutate<{ validateEmail }>({
mutation: VALIDATE_EMAIL,
variables: {
token: this.token,
},
});
this.loading = false;
return await this.$router.push({ name: RouteName.HOME });
} catch (err) {
console.error(err);
this.failed = true;
}
}
}
</script>

View File

@ -1,92 +0,0 @@
<template>
<section class="section container">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.UPDATE_IDENTITY }">{{ $t('My account') }}</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.PASSWORD_CHANGE }" aria-current="page">{{ $t('Password change') }}</router-link></li>
</ul>
</nav>
<h1 class="title">{{ $t('Password') }}</h1>
<b-notification
type="is-danger"
has-icon
aria-close-label="Close notification"
role="alert"
:key="error"
v-for="error in errors"
>
{{ error }}
</b-notification>
<form @submit="resetAction" class="form">
<b-field :label="$t('Old password')">
<b-input
aria-required="true"
required
type="password"
password-reveal
minlength="6"
v-model="oldPassword"
/>
</b-field>
<b-field :label="$t('New password')">
<b-input
aria-required="true"
required
type="password"
password-reveal
minlength="6"
v-model="newPassword"
/>
</b-field>
<button class="button is-primary">
{{ $t('Change my password') }}
</button>
</form>
</section>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { CHANGE_PASSWORD } from '@/graphql/user';
import { RouteName } from '@/router';
@Component
export default class PasswordChange extends Vue {
oldPassword: string = '';
newPassword: string = '';
errors: string[] = [];
RouteName = RouteName;
async resetAction(e) {
e.preventDefault();
this.errors = [];
try {
await this.$apollo.mutate({
mutation: CHANGE_PASSWORD,
variables: {
oldPassword: this.oldPassword,
newPassword: this.newPassword,
},
});
this.$notifier.success(this.$t('The password was successfully changed') as string);
} catch (err) {
this.handleError(err);
}
}
private handleError(err: any) {
console.error(err);
if (err.graphQLErrors !== undefined) {
err.graphQLErrors.forEach(({ message }) => {
this.errors.push(message);
});
}
}
}
</script>
<style lang="scss">
</style>

View File

@ -20,7 +20,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
%{context: %{current_user: %User{id: id} = user}} %{context: %{current_user: %User{id: id} = user}}
) do ) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, actor_id), with {:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
{:ok, feed_token} <- Events.create_feed_token(%{"user_id" => id, "actor_id" => actor_id}) do {:ok, feed_token} <- Events.create_feed_token(%{user_id: id, actor_id: actor_id}) do
{:ok, feed_token} {:ok, feed_token}
else else
{:is_owned, nil} -> {:is_owned, nil} ->
@ -33,7 +33,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
""" """
@spec create_feed_token(any, map, map) :: {:ok, FeedToken.t()} @spec create_feed_token(any, map, map) :: {:ok, FeedToken.t()}
def create_feed_token(_parent, %{}, %{context: %{current_user: %User{id: id}}}) do def create_feed_token(_parent, %{}, %{context: %{current_user: %User{id: id}}}) do
with {:ok, feed_token} <- Events.create_feed_token(%{"user_id" => id}) do with {:ok, feed_token} <- Events.create_feed_token(%{user_id: id}) do
{:ok, feed_token} {:ok, feed_token}
end end
end end

View File

@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
alias Mobilizon.{Actors, Config, Events, Users} alias Mobilizon.{Actors, Config, Events, Users}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Crypto
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Mobilizon.Users.User alias Mobilizon.Users.User
@ -14,6 +15,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
require Logger require Logger
@confirmation_token_length 30
@doc """ @doc """
Find an user by its ID Find an user by its ID
""" """
@ -298,4 +301,82 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
def change_password(_parent, _args, _resolution) do def change_password(_parent, _args, _resolution) do
{:error, "You need to be logged-in to change your password"} {:error, "You need to be logged-in to change your password"}
end end
def change_email(_parent, %{email: new_email, password: password}, %{
context: %{current_user: %User{email: old_email, password_hash: password_hash} = user}
}) do
with {:current_password, true} <-
{:current_password, Argon2.verify_pass(password, password_hash)},
{:same_email, false} <- {:same_email, new_email == old_email},
{:email_valid, true} <- {:email_valid, Email.Checker.valid?(new_email)},
{:ok, %User{} = user} <-
user
|> User.changeset(%{
unconfirmed_email: new_email,
confirmation_token: Crypto.random_string(@confirmation_token_length),
confirmation_sent_at: DateTime.utc_now() |> DateTime.truncate(:second)
})
|> Repo.update() do
user
|> Email.User.send_email_reset_old_email()
|> Email.Mailer.deliver_later()
user
|> Email.User.send_email_reset_new_email()
|> Email.Mailer.deliver_later()
{:ok, user}
else
{:current_password, false} ->
{:error, "The password provided is invalid"}
{:same_email, true} ->
{:error, "The new email must be different"}
{:email_valid, _} ->
{:error, "The new email doesn't seem to be valid"}
end
end
def change_email(_parent, _args, _resolution) do
{:error, "You need to be logged-in to change your email"}
end
def validate_email(_parent, %{token: token}, _resolution) do
with %User{} = user <- Users.get_user_by_activation_token(token),
{:ok, %User{} = user} <-
user
|> User.changeset(%{
email: user.unconfirmed_email,
unconfirmed_email: nil,
confirmation_token: nil,
confirmation_sent_at: nil
})
|> Repo.update() do
{:ok, user}
end
end
def delete_account(_parent, %{password: password}, %{
context: %{current_user: %User{password_hash: password_hash} = user}
}) do
with {:current_password, true} <-
{:current_password, Argon2.verify_pass(password, password_hash)},
actors <- Users.get_actors_for_user(user),
# Detach actors from user
:ok <- Enum.each(actors, fn actor -> Actors.update_actor(actor, %{user_id: nil}) end),
# Launch a background job to delete actors
:ok <- Enum.each(actors, &Actors.delete_actor/1),
# Delete user
{:ok, user} <- Users.delete_user(user) do
{:ok, user}
else
{:current_password, false} ->
{:error, "The password provided is invalid"}
end
end
def delete_account(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete your account"}
end
end end

View File

@ -178,5 +178,21 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
arg(:new_password, non_null(:string)) arg(:new_password, non_null(:string))
resolve(&User.change_password/3) resolve(&User.change_password/3)
end end
field :change_email, :user do
arg(:email, non_null(:string))
arg(:password, non_null(:string))
resolve(&User.change_email/3)
end
field :validate_email, :user do
arg(:token, non_null(:string))
resolve(&User.validate_email/3)
end
field :delete_account, :deleted_object do
arg(:password, non_null(:string))
resolve(&User.delete_account/3)
end
end end
end end

View File

@ -186,7 +186,7 @@ defmodule Mobilizon.Actors do
%Actor{} %Actor{}
|> Actor.registration_changeset(args) |> Actor.registration_changeset(args)
|> Repo.insert() do |> Repo.insert() do
Events.create_feed_token(%{"user_id" => args["user_id"], "actor_id" => person.id}) Events.create_feed_token(%{user_id: args["user_id"], actor_id: person.id})
{:ok, person} {:ok, person}
end end

View File

@ -1367,7 +1367,7 @@ defmodule Mobilizon.Events do
""" """
@spec create_feed_token(map) :: {:ok, FeedToken.t()} | {:error, Changeset.t()} @spec create_feed_token(map) :: {:ok, FeedToken.t()} | {:error, Changeset.t()}
def create_feed_token(attrs \\ %{}) do def create_feed_token(attrs \\ %{}) do
attrs = Map.put(attrs, "token", Ecto.UUID.generate()) attrs = Map.put(attrs, :token, Ecto.UUID.generate())
%FeedToken{} %FeedToken{}
|> FeedToken.changeset(attrs) |> FeedToken.changeset(attrs)

View File

@ -39,11 +39,12 @@ defmodule Mobilizon.Users.User do
:confirmation_token, :confirmation_token,
:reset_password_sent_at, :reset_password_sent_at,
:reset_password_token, :reset_password_token,
:locale :locale,
:unconfirmed_email
] ]
@attrs @required_attrs ++ @optional_attrs @attrs @required_attrs ++ @optional_attrs
@registration_required_attrs [:email, :password] @registration_required_attrs @required_attrs ++ [:password]
@password_change_required_attrs [:password] @password_change_required_attrs [:password]
@password_reset_required_attrs @password_change_required_attrs ++ @password_reset_required_attrs @password_change_required_attrs ++
@ -61,6 +62,7 @@ defmodule Mobilizon.Users.User do
field(:confirmation_token, :string) field(:confirmation_token, :string)
field(:reset_password_sent_at, :utc_datetime) field(:reset_password_sent_at, :utc_datetime)
field(:reset_password_token, :string) field(:reset_password_token, :string)
field(:unconfirmed_email, :string)
field(:locale, :string, default: "en") field(:locale, :string, default: "en")
belongs_to(:default_actor, Actor) belongs_to(:default_actor, Actor)
@ -99,7 +101,7 @@ defmodule Mobilizon.Users.User do
|> save_confirmation_token() |> save_confirmation_token()
|> unique_constraint( |> unique_constraint(
:confirmation_token, :confirmation_token,
message: "The registration is already in use, this looks like an issue on our side." message: "The registration token is already in use, this looks like an issue on our side."
) )
end end

View File

@ -31,7 +31,7 @@ defmodule Mobilizon.Users do
%User{} %User{}
|> User.registration_changeset(args) |> User.registration_changeset(args)
|> Repo.insert() do |> Repo.insert() do
Events.create_feed_token(%{"user_id" => user.id}) Events.create_feed_token(%{user_id: user.id})
{:ok, user} {:ok, user}
end end
@ -267,7 +267,10 @@ defmodule Mobilizon.Users do
@spec user_by_email_query(String.t(), boolean | nil) :: Ecto.Query.t() @spec user_by_email_query(String.t(), boolean | nil) :: Ecto.Query.t()
defp user_by_email_query(email, nil) do defp user_by_email_query(email, nil) do
from(u in User, where: u.email == ^email, preload: :default_actor) from(u in User,
where: u.email == ^email or u.unconfirmed_email == ^email,
preload: :default_actor
)
end end
defp user_by_email_query(email, true) do defp user_by_email_query(email, true) do
@ -281,7 +284,7 @@ defmodule Mobilizon.Users do
defp user_by_email_query(email, false) do defp user_by_email_query(email, false) do
from( from(
u in User, u in User,
where: u.email == ^email and is_nil(u.confirmed_at), where: (u.email == ^email or u.unconfirmed_email == ^email) and is_nil(u.confirmed_at),
preload: :default_actor preload: :default_actor
) )
end end

View File

@ -61,9 +61,10 @@ defmodule Mobilizon.Web.Email.User do
with %User{} = user <- Users.get_user_by_activation_token(token), with %User{} = user <- Users.get_user_by_activation_token(token),
{:ok, %User{} = user} <- {:ok, %User{} = user} <-
Users.update_user(user, %{ Users.update_user(user, %{
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second), confirmed_at: DateTime.utc_now() |> DateTime.truncate(:second),
"confirmation_sent_at" => nil, confirmation_sent_at: nil,
"confirmation_token" => nil confirmation_token: nil,
email: user.unconfirmed_email || user.email
}) do }) do
Logger.info("User #{user.email} has been confirmed") Logger.info("User #{user.email} has been confirmed")
{:ok, user} {:ok, user}
@ -141,6 +142,48 @@ defmodule Mobilizon.Web.Email.User do
end end
end end
def send_email_reset_old_email(
%User{locale: user_locale, email: email, unconfirmed_email: unconfirmed_email} = _user,
_locale \\ "en"
) do
Gettext.put_locale(user_locale)
subject =
gettext(
"Mobilizon on %{instance}: email changed",
instance: Config.instance_name()
)
Email.base_email(to: email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:new_email, unconfirmed_email)
|> render(:email_changed_old)
end
def send_email_reset_new_email(
%User{
locale: user_locale,
unconfirmed_email: unconfirmed_email,
confirmation_token: confirmation_token
} = _user,
_locale \\ "en"
) do
Gettext.put_locale(user_locale)
subject =
gettext(
"Mobilizon on %{instance}: confirm your email address",
instance: Config.instance_name()
)
Email.base_email(to: unconfirmed_email, subject: subject)
|> assign(:locale, user_locale)
|> assign(:subject, subject)
|> assign(:token, confirmation_token)
|> render(:email_changed_new)
end
@spec we_can_send_email(User.t(), atom) :: :ok | {:error, :email_too_soon} @spec we_can_send_email(User.t(), atom) :: :ok | {:error, :email_too_soon}
defp we_can_send_email(%User{} = user, key) do defp we_can_send_email(%User{} = user, key) do
case Map.get(user, key) do case Map.get(user, key) do

View File

@ -130,6 +130,8 @@ defmodule Mobilizon.Web.Router do
as: "participation_email_confirmation" as: "participation_email_confirmation"
) )
get("/validate/email/:token", PageController, :index, as: "user_email_validation")
get("/interact", PageController, :interact) get("/interact", PageController, :interact)
end end

View File

@ -0,0 +1,75 @@
<!-- HERO -->
<tr>
<td bgcolor="#424056" align="center" style="padding: 0px 10px 0px 10px;">
<!--[if (gte mso 9)|(IE)]>
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
<tr>
<td align="center" valign="top" width="600">
<![endif]-->
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
<tr>
<td bgcolor="#ffffff" align="center" valign="top" style="padding: 40px 20px 20px 20px; border-radius: 4px 4px 0px 0px; color: #111111; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
<h1 style="font-size: 48px; font-weight: 400; margin: 0;">
<%= gettext "Verify email address" %>
</h1>
</td>
</tr>
</table>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
<!-- COPY BLOCK -->
<tr>
<td bgcolor="#f4f4f4" align="center" style="padding: 0px 10px 0px 10px;">
<!--[if (gte mso 9)|(IE)]>
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
<tr>
<td align="center" valign="top" width="600">
<![endif]-->
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
<!-- COPY -->
<tr>
<td bgcolor="#ffffff" align="left" style="padding: 20px 30px 0px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
<p style="margin: 0;">
<%= gettext "Confirm the new address to change your email." %>
</p>
</td>
</tr>
<tr>
<td bgcolor="#ffffff" align="left">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#ffffff" align="center" style="padding: 20px 30px 60px 30px;">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center" style="border-radius: 3px;" bgcolor="#424056">
<a href="<%= user_email_validation_url(Mobilizon.Web.Endpoint, :index, @token) %>" target="_blank" style="font-size: 20px; font-family: Helvetica, Arial, sans-serif; color: #ffffff; text-decoration: none; color: #ffffff; text-decoration: none; padding: 15px 25px; border-radius: 2px; border: 1px solid #424056; display: inline-block;">
<%= gettext "Verify email address" %>
</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #777777; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 400; line-height: 20px;" >
<p style="margin: 0">
<%= gettext "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above." %>
</p>
</td>
</tr>
</table>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>

View File

@ -0,0 +1,10 @@
<%= gettext "Verify email address" %>
==
<%= gettext "Confirm the new address to change your email." %>
<%= user_email_validation_url(Mobilizon.Web.Endpoint, :index, @token) %>
<%= gettext "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above." %>

View File

@ -0,0 +1,73 @@
<!-- HERO -->
<tr>
<td bgcolor="#424056" align="center" style="padding: 0px 10px 0px 10px;">
<!--[if (gte mso 9)|(IE)]>
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
<tr>
<td align="center" valign="top" width="600">
<![endif]-->
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
<tr>
<td bgcolor="#ffffff" align="center" valign="top" style="padding: 40px 20px 20px 20px; border-radius: 4px 4px 0px 0px; color: #111111; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
<h1 style="font-size: 48px; font-weight: 400; margin: 0;">
<%= gettext "New email address" %>
</h1>
</td>
</tr>
</table>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
<!-- COPY BLOCK -->
<tr>
<td bgcolor="#f4f4f4" align="center" style="padding: 0px 10px 0px 10px;">
<!--[if (gte mso 9)|(IE)]>
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
<tr>
<td align="center" valign="top" width="600">
<![endif]-->
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
<!-- COPY -->
<tr>
<td bgcolor="#ffffff" align="left" style="padding: 20px 30px 0px 30px; color: #666666; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
<p style="margin: 0;">
<%= gettext "The email address for your account on %{host} is being changed to:", host: @instance[:name] %>
</p>
</td>
</tr>
<tr>
<td bgcolor="#ffffff" align="left">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#ffffff" align="center" style="padding: 20px 30px 60px 30px;">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td align="center">
<%= @new_email %>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td bgcolor="#ffffff" align="left" style="padding: 20px 30px 40px 30px; color: #777777; font-family: 'Lato', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 400; line-height: 20px;" >
<p style="margin: 0">
<%= gettext "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account." %>
</p>
</td>
</tr>
</table>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>

View File

@ -0,0 +1,9 @@
<%= gettext "New email address" %>
==
<%= gettext "The email address for your account on %{host} is being changed to:", host: @instance[:name] %>
<%= @new_email %>
<%= gettext "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account." %>

View File

@ -625,3 +625,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -622,3 +622,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -649,3 +649,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -622,3 +622,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -654,3 +654,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -608,3 +608,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -631,3 +631,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -622,3 +622,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -738,3 +738,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "Mitä tietoja kerätään?" msgstr "Mitä tietoja kerätään?"
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -10,627 +10,563 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"POT-Creation-Date: \n" "POT-Creation-Date: \n"
"PO-Revision-Date: 2020-01-09 21:14+0000\n" "PO-Revision-Date: 2020-02-13 15:57+0100\n"
"Last-Translator: matograine <tom.ngr@zaclys.net>\n" "Last-Translator: matograine <tom.ngr@zaclys.net>\n"
"Language-Team: French <https://weblate.framasoft.org/projects/mobilizon/" "Language-Team: French <https://weblate.framasoft.org/projects/mobilizon/backend/fr/>\n"
"backend/fr/>\n"
"Language: fr\n" "Language: fr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 3.9.1\n" "X-Generator: Poedit 2.0.6\n"
#, elixir-format #: lib/web/templates/email/password_reset.html.eex:48 lib/web/templates/email/password_reset.text.eex:12
#: lib/web/templates/email/password_reset.html.eex:48
#: lib/web/templates/email/password_reset.text.eex:12
msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one." msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one."
msgstr "" msgstr "Si vous n'avez pas demandé ceci, vous pouvez ignorer cet email. Votre mot de passe ne changera pas tant que vous n'en créerez pas un nouveau en cliquant sur le lien ci-dessous."
"Si vous n'avez pas demandé ceci, vous pouvez ignorer cet email. Votre mot de "
"passe ne changera pas tant que vous n'en créerez pas un nouveau en cliquant "
"sur le lien ci-dessous."
#, elixir-format
#: lib/service/export/feed.ex:169 #: lib/service/export/feed.ex:169
msgid "Feed for %{email} on Mobilizon" msgid "Feed for %{email} on Mobilizon"
msgstr "Flux pour %{email} sur Mobilizon" msgstr "Flux pour %{email} sur Mobilizon"
#, elixir-format #: lib/web/templates/email/email.html.eex:155 lib/web/templates/email/email.text.eex:16
#: lib/web/templates/email/email.html.eex:155
#: lib/web/templates/email/email.text.eex:16
msgid "%{instance} is a Mobilizon server." msgid "%{instance} is a Mobilizon server."
msgstr "%{instance} est une instance Mobilizon." msgstr "%{instance} est une instance Mobilizon."
#, elixir-format
#: lib/web/templates/email/report.html.eex:41 #: lib/web/templates/email/report.html.eex:41
msgid "%{reporter_name} (%{reporter_username}) reported the following content." msgid "%{reporter_name} (%{reporter_username}) reported the following content."
msgstr "%{reporter_name} (%{reporter_username}) a signalé le contenu suivant." msgstr "%{reporter_name} (%{reporter_username}) a signalé le contenu suivant."
#, elixir-format
#: lib/web/templates/email/report.html.eex:52 #: lib/web/templates/email/report.html.eex:52
msgid "%{title} by %{creator}" msgid "%{title} by %{creator}"
msgstr "%{title} par %{creator}" msgstr "%{title} par %{creator}"
#, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:58 #: lib/web/templates/email/registration_confirmation.html.eex:58
msgid "Activate my account" msgid "Activate my account"
msgstr "Activer mon compte" msgstr "Activer mon compte"
#, elixir-format #: lib/web/templates/email/email.html.eex:124 lib/web/templates/email/email.text.eex:14
#: lib/web/templates/email/email.html.eex:124
#: lib/web/templates/email/email.text.eex:14
msgid "Ask the community on Framacolibri" msgid "Ask the community on Framacolibri"
msgstr "Demander à la communauté sur Framacolibri" msgstr "Demander à la communauté sur Framacolibri"
#, elixir-format #: lib/web/templates/email/report.html.eex:66 lib/web/templates/email/report.text.eex:13
#: lib/web/templates/email/report.html.eex:66
#: lib/web/templates/email/report.text.eex:13
msgid "Comments" msgid "Comments"
msgstr "Commentaires" msgstr "Commentaires"
#, elixir-format #: lib/web/templates/email/report.html.eex:50 lib/web/templates/email/report.text.eex:6
#: lib/web/templates/email/report.html.eex:50
#: lib/web/templates/email/report.text.eex:6
msgid "Event" msgid "Event"
msgstr "Événement" msgstr "Événement"
#, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:45 #: lib/web/templates/email/registration_confirmation.html.eex:45
msgid "If you didn't request this, please ignore this email." msgid "If you didn't request this, please ignore this email."
msgstr "Si vous n'avez pas demandé ceci, merci d'ignorer cet email." msgstr "Si vous n'avez pas demandé ceci, merci d'ignorer cet email."
#, elixir-format
#: lib/web/email/user.ex:48 #: lib/web/email/user.ex:48
msgid "Instructions to reset your password on %{instance}" msgid "Instructions to reset your password on %{instance}"
msgstr "Instructions pour réinitialiser votre mot de passe sur %{instance}" msgstr "Instructions pour réinitialiser votre mot de passe sur %{instance}"
#, elixir-format
#: lib/web/templates/email/email.html.eex:156 #: lib/web/templates/email/email.html.eex:156
msgid "Learn more about Mobilizon." msgid "Learn more about Mobilizon."
msgstr "En apprendre plus à propos de Mobilizon." msgstr "En apprendre plus à propos de Mobilizon."
#, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:13 #: lib/web/templates/email/registration_confirmation.html.eex:13
msgid "Nearly here!" msgid "Nearly here!"
msgstr "Vous y êtes presque !" msgstr "Vous y êtes presque !"
#, elixir-format #: lib/web/templates/email/email.html.eex:121 lib/web/templates/email/email.text.eex:12
#: lib/web/templates/email/email.html.eex:121
#: lib/web/templates/email/email.text.eex:12
msgid "Need some help? Something not working properly?" msgid "Need some help? Something not working properly?"
msgstr "Besoin d'aide ? Quelque chose ne fonctionne pas correctement ?" msgstr "Besoin d'aide ? Quelque chose ne fonctionne pas correctement ?"
#, elixir-format
#: lib/web/templates/email/report.html.eex:13 #: lib/web/templates/email/report.html.eex:13
msgid "New report on %{instance}" msgid "New report on %{instance}"
msgstr "Nouveau signalement sur %{instance}" msgstr "Nouveau signalement sur %{instance}"
#, elixir-format #: lib/web/templates/email/report.html.eex:84 lib/web/templates/email/report.text.eex:22
#: lib/web/templates/email/report.html.eex:84
#: lib/web/templates/email/report.text.eex:22
msgid "Reason" msgid "Reason"
msgstr "Raison" msgstr "Raison"
#, elixir-format
#: lib/web/templates/email/password_reset.html.eex:61 #: lib/web/templates/email/password_reset.html.eex:61
msgid "Reset Password" msgid "Reset Password"
msgstr "Réinitialiser mon mot de passe" msgstr "Réinitialiser mon mot de passe"
#, elixir-format
#: lib/web/templates/email/password_reset.html.eex:41 #: lib/web/templates/email/password_reset.html.eex:41
msgid "Resetting your password is easy. Just press the button below and follow the instructions. We'll have you up and running in no time." msgid "Resetting your password is easy. Just press the button below and follow the instructions. We'll have you up and running in no time."
msgstr "Réinitialiser votre mot de passe est facile. Cliquez simplement sur le bouton et suivez les inscriptions. Vous serez opérationnel en un rien de temps." msgstr "Réinitialiser votre mot de passe est facile. Cliquez simplement sur le bouton et suivez les inscriptions. Vous serez opérationnel en un rien de temps."
#, elixir-format
#: lib/web/templates/email/password_reset.html.eex:13 #: lib/web/templates/email/password_reset.html.eex:13
msgid "Trouble signing in?" msgid "Trouble signing in?"
msgstr "Des problèmes à vous connecter ?" msgstr "Des problèmes à vous connecter ?"
#, elixir-format
#: lib/web/templates/email/report.html.eex:104 #: lib/web/templates/email/report.html.eex:104
msgid "View the report" msgid "View the report"
msgstr "Voir le signalement" msgstr "Voir le signalement"
#, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:38 #: lib/web/templates/email/registration_confirmation.html.eex:38
msgid "You created an account on %{host} with this email address. You are one click away from activating it." msgid "You created an account on %{host} with this email address. You are one click away from activating it."
msgstr "Vous avez créé un compte sur %{host} avec cette adresse email. Vous êtes à un clic de l'activer." msgstr "Vous avez créé un compte sur %{host} avec cette adresse email. Vous êtes à un clic de l'activer."
#, elixir-format
#: lib/web/email/user.ex:28 #: lib/web/email/user.ex:28
msgid "Instructions to confirm your Mobilizon account on %{instance}" msgid "Instructions to confirm your Mobilizon account on %{instance}"
msgstr "Instructions pour confirmer votre compte Mobilizon sur %{instance}" msgstr "Instructions pour confirmer votre compte Mobilizon sur %{instance}"
#, elixir-format
#: lib/web/email/admin.ex:23 #: lib/web/email/admin.ex:23
msgid "New report on Mobilizon instance %{instance}" msgid "New report on Mobilizon instance %{instance}"
msgstr "Nouveau signalement sur l'instance Mobilizon %{instance}" msgstr "Nouveau signalement sur l'instance Mobilizon %{instance}"
#, elixir-format
#: lib/web/templates/email/registration_confirmation.text.eex:1 #: lib/web/templates/email/registration_confirmation.text.eex:1
msgid "Activate your account" msgid "Activate your account"
msgstr "Activer mon compte" msgstr "Activer mon compte"
#, elixir-format
#: lib/web/templates/email/event_participation_approved.html.eex:13 #: lib/web/templates/email/event_participation_approved.html.eex:13
msgid "All good!" msgid "All good!"
msgstr "Tout est bon !" msgstr "Tout est bon !"
#, elixir-format #: lib/web/templates/email/event_participation_approved.html.eex:45 lib/web/templates/email/event_participation_approved.text.eex:7
#: lib/web/templates/email/event_participation_approved.html.eex:45
#: lib/web/templates/email/event_participation_approved.text.eex:7
msgid "An organizer just approved your participation. You're now going to this event!" msgid "An organizer just approved your participation. You're now going to this event!"
msgstr "Un⋅e organisateur⋅ice vient d'approuver votre participation. Vous allez désormais à cet événement !" msgstr "Un⋅e organisateur⋅ice vient d'approuver votre participation. Vous allez désormais à cet événement !"
#, elixir-format #: lib/web/templates/email/event_participation_approved.html.eex:58 lib/web/templates/email/event_updated.html.eex:101
#: lib/web/templates/email/event_participation_approved.html.eex:58
#: lib/web/templates/email/event_updated.html.eex:101
msgid "Go to event page" msgid "Go to event page"
msgstr "Aller à la page de l'événement" msgstr "Aller à la page de l'événement"
#, elixir-format #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:70 lib/web/templates/email/event_participation_approved.html.eex:70 lib/web/templates/email/event_updated.html.eex:113 lib/web/templates/email/event_updated.text.eex:21
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:70
#: lib/web/templates/email/event_participation_approved.html.eex:70 lib/web/templates/email/event_updated.html.eex:113
#: lib/web/templates/email/event_updated.text.eex:21
msgid "If you need to cancel your participation, just access the event page through link above and click on the participation button." msgid "If you need to cancel your participation, just access the event page through link above and click on the participation button."
msgstr "Si vous avez besoin d'annuler votre participation, il suffit d'accéder à la page de l'événement à partir du lien ci-dessus et de cliquer sur le bouton de participation." msgstr "Si vous avez besoin d'annuler votre participation, il suffit d'accéder à la page de l'événement à partir du lien ci-dessus et de cliquer sur le bouton de participation."
#, elixir-format #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:11 lib/web/templates/email/event_participation_approved.text.eex:11
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:11
#: lib/web/templates/email/event_participation_approved.text.eex:11
msgid "If you need to cancel your participation, just access the previous link and click on the participation button." msgid "If you need to cancel your participation, just access the previous link and click on the participation button."
msgstr "Si vous avez besoin d'annuler votre participation, accédez au lien ci-dessus et cliquez sur le bouton de participation." msgstr "Si vous avez besoin d'annuler votre participation, accédez au lien ci-dessus et cliquez sur le bouton de participation."
#, elixir-format
#: lib/web/templates/email/email.text.eex:16 #: lib/web/templates/email/email.text.eex:16
msgid "Learn more about Mobilizon:" msgid "Learn more about Mobilizon:"
msgstr "En apprendre plus à propos de Mobilizon :" msgstr "En apprendre plus à propos de Mobilizon :"
#, elixir-format
#: lib/web/templates/email/report.text.eex:1 #: lib/web/templates/email/report.text.eex:1
msgid "New report from %{reporter} on %{instance}" msgid "New report from %{reporter} on %{instance}"
msgstr "Nouveau signalement sur %{instance}" msgstr "Nouveau signalement sur %{instance}"
#, elixir-format
#: lib/web/templates/email/event_participation_approved.text.eex:1 #: lib/web/templates/email/event_participation_approved.text.eex:1
msgid "Participation approved" msgid "Participation approved"
msgstr "Participation approuvée" msgstr "Participation approuvée"
#, elixir-format
#: lib/web/templates/email/event_participation_rejected.text.eex:1 #: lib/web/templates/email/event_participation_rejected.text.eex:1
msgid "Participation rejected" msgid "Participation rejected"
msgstr "Participation refusée" msgstr "Participation refusée"
#, elixir-format
#: lib/web/templates/email/password_reset.text.eex:1 #: lib/web/templates/email/password_reset.text.eex:1
msgid "Password reset" msgid "Password reset"
msgstr "Réinitialisation du mot de passe" msgstr "Réinitialisation du mot de passe"
#, elixir-format
#: lib/web/templates/email/password_reset.text.eex:7 #: lib/web/templates/email/password_reset.text.eex:7
msgid "Resetting your password is easy. Just click the link below and follow the instructions. We'll have you up and running in no time." msgid "Resetting your password is easy. Just click the link below and follow the instructions. We'll have you up and running in no time."
msgstr "Réinitialiser votre mot de passe est facile. Cliquez simplement sur le bouton et suivez les inscriptions. Vous serez opérationnel en un rien de temps." msgstr "Réinitialiser votre mot de passe est facile. Cliquez simplement sur le bouton et suivez les inscriptions. Vous serez opérationnel en un rien de temps."
#, elixir-format
#: lib/web/templates/email/event_participation_rejected.html.eex:13 #: lib/web/templates/email/event_participation_rejected.html.eex:13
msgid "Sorry!" msgid "Sorry!"
msgstr "Désolé !" msgstr "Désolé !"
#, elixir-format #: lib/web/templates/email/event_participation_rejected.html.eex:45 lib/web/templates/email/event_participation_rejected.text.eex:7
#: lib/web/templates/email/event_participation_rejected.html.eex:45
#: lib/web/templates/email/event_participation_rejected.text.eex:7
msgid "Unfortunately, the organizers rejected your participation." msgid "Unfortunately, the organizers rejected your participation."
msgstr "Malheureusement, les organisateur⋅ices ont rejeté votre demande de participation." msgstr "Malheureusement, les organisateur⋅ices ont rejeté votre demande de participation."
#, elixir-format
#: lib/web/templates/email/registration_confirmation.text.eex:5 #: lib/web/templates/email/registration_confirmation.text.eex:5
msgid "You created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email." msgid "You created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email."
msgstr "Vous avez créé un compte sur %{host} avec cette adresse email. Vous êtes à un clic de l'activer." msgstr "Vous avez créé un compte sur %{host} avec cette adresse email. Vous êtes à un clic de l'activer."
#, elixir-format #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:38 lib/web/templates/email/event_participation_approved.html.eex:38
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:38
#: lib/web/templates/email/event_participation_approved.html.eex:38
msgid "You requested to participate in event %{title}" msgid "You requested to participate in event %{title}"
msgstr "Vous avez demandé à participer à l'événement %{title}" msgstr "Vous avez demandé à participer à l'événement %{title}"
#, elixir-format #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:5 lib/web/templates/email/event_participation_approved.text.eex:5 lib/web/templates/email/event_participation_rejected.html.eex:38 lib/web/templates/email/event_participation_rejected.text.eex:5
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:5
#: lib/web/templates/email/event_participation_approved.text.eex:5 lib/web/templates/email/event_participation_rejected.html.eex:38
#: lib/web/templates/email/event_participation_rejected.text.eex:5
msgid "You requested to participate in event %{title}." msgid "You requested to participate in event %{title}."
msgstr "Vous avez demandé à participer à l'événement %{title}." msgstr "Vous avez demandé à participer à l'événement %{title}."
#, elixir-format
#: lib/web/email/participation.ex:91 #: lib/web/email/participation.ex:91
msgid "Your participation to event %{title} has been approved" msgid "Your participation to event %{title} has been approved"
msgstr "Votre participation à l'événement %{title} a été approuvée" msgstr "Votre participation à l'événement %{title} a été approuvée"
#, elixir-format
#: lib/web/email/participation.ex:70 #: lib/web/email/participation.ex:70
msgid "Your participation to event %{title} has been rejected" msgid "Your participation to event %{title} has been rejected"
msgstr "Votre participation à l'événement %{title} a été rejetée" msgstr "Votre participation à l'événement %{title} a été rejetée"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:82 #: lib/web/templates/email/event_updated.html.eex:82
msgid "Ending of event" msgid "Ending of event"
msgstr "Fin de l'événement" msgstr "Fin de l'événement"
#, elixir-format
#: lib/web/email/event.ex:35 #: lib/web/email/event.ex:35
msgid "Event %{title} has been updated" msgid "Event %{title} has been updated"
msgstr "L'événement %{title} a été mis à jour" msgstr "L'événement %{title} a été mis à jour"
#, elixir-format #: lib/web/templates/email/event_updated.html.eex:13 lib/web/templates/email/event_updated.text.eex:1
#: lib/web/templates/email/event_updated.html.eex:13
#: lib/web/templates/email/event_updated.text.eex:1
msgid "Event updated!" msgid "Event updated!"
msgstr "Événement mis à jour !" msgstr "Événement mis à jour !"
#, elixir-format
#: lib/web/templates/email/event_updated.text.eex:16 #: lib/web/templates/email/event_updated.text.eex:16
msgid "New date and time for ending of event: %{ends_on}" msgid "New date and time for ending of event: %{ends_on}"
msgstr "Nouvelle date et heure de fin de l'événement : %{ends_on}" msgstr "Nouvelle date et heure de fin de l'événement : %{ends_on}"
#, elixir-format
#: lib/web/templates/email/event_updated.text.eex:12 #: lib/web/templates/email/event_updated.text.eex:12
msgid "New date and time for start of event: %{begins_on}" msgid "New date and time for start of event: %{begins_on}"
msgstr "Nouvelle date et heure de début de l'événement : %{begins_on}" msgstr "Nouvelle date et heure de début de l'événement : %{begins_on}"
#, elixir-format
#: lib/web/templates/email/event_updated.text.eex:8 #: lib/web/templates/email/event_updated.text.eex:8
msgid "New title: %{title}" msgid "New title: %{title}"
msgstr "Nouveau titre : %{title}" msgstr "Nouveau titre : %{title}"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:72 #: lib/web/templates/email/event_updated.html.eex:72
msgid "Start of event" msgid "Start of event"
msgstr "Début de l'événement" msgstr "Début de l'événement"
#, elixir-format
#: lib/web/templates/email/event_updated.text.eex:5 #: lib/web/templates/email/event_updated.text.eex:5
msgid "The event %{title} was just updated" msgid "The event %{title} was just updated"
msgstr "L'événement %{title} vient d'être mis à jour" msgstr "L'événement %{title} vient d'être mis à jour"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:38 #: lib/web/templates/email/event_updated.html.eex:38
msgid "The event %{title} was updated" msgid "The event %{title} was updated"
msgstr "L'événement %{title} a été mis à jour" msgstr "L'événement %{title} a été mis à jour"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:62 #: lib/web/templates/email/event_updated.html.eex:62
msgid "Title" msgid "Title"
msgstr "Titre" msgstr "Titre"
#, elixir-format
#: lib/web/templates/email/event_updated.text.eex:19 #: lib/web/templates/email/event_updated.text.eex:19
msgid "View the updated event on: %{link}" msgid "View the updated event on: %{link}"
msgstr "Voir l'événement mis à jour sur : %{link}" msgstr "Voir l'événement mis à jour sur : %{link}"
#, elixir-format #: lib/web/templates/email/password_reset.html.eex:38 lib/web/templates/email/password_reset.text.eex:5
#: lib/web/templates/email/password_reset.html.eex:38
#: lib/web/templates/email/password_reset.text.eex:5
msgid "You requested a new password for your account on %{instance}." msgid "You requested a new password for your account on %{instance}."
msgstr "Vous avez demandé un nouveau mot de passe pour votre compte sur %{instance}." msgstr "Vous avez demandé un nouveau mot de passe pour votre compte sur %{instance}."
#, elixir-format
#: lib/web/templates/email/email.html.eex:95 #: lib/web/templates/email/email.html.eex:95
msgid "In the meantime, please consider that the software is not (yet) finished. More information %{a_start}on our blog%{a_end}." msgid "In the meantime, please consider that the software is not (yet) finished. More information %{a_start}on our blog%{a_end}."
msgstr "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Plus d'informations %{a_start}sur notre blog%{a_end}." msgstr "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Plus d'informations %{a_start}sur notre blog%{a_end}."
#, elixir-format
#: lib/web/templates/email/email.html.eex:94 #: lib/web/templates/email/email.html.eex:94
msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of %{b_start}version 1 of the software in the first half of 2020%{b_end}." msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of %{b_start}version 1 of the software in the first half of 2020%{b_end}."
msgstr "Mobilizon est en cours de développement, nous ajouterons de nouvelles fonctionnalités à ce site lors de mises à jour régulières, jusqu'à la publication de %{b_start}la version 1 du logiciel au premier semestre 2020%{b_end}." msgstr "Mobilizon est en cours de développement, nous ajouterons de nouvelles fonctionnalités à ce site lors de mises à jour régulières, jusqu'à la publication de %{b_start}la version 1 du logiciel au premier semestre 2020%{b_end}."
#, elixir-format #: lib/web/templates/email/email.html.eex:91 lib/web/templates/email/email.text.eex:6
#: lib/web/templates/email/email.html.eex:91
#: lib/web/templates/email/email.text.eex:6
msgid "This is a demonstration site to test the beta version of Mobilizon." msgid "This is a demonstration site to test the beta version of Mobilizon."
msgstr "Ceci est un site de démonstration permettant de tester la version bêta de Mobilizon." msgstr "Ceci est un site de démonstration permettant de tester la version bêta de Mobilizon."
#, elixir-format
#: lib/web/templates/email/email.html.eex:89 #: lib/web/templates/email/email.html.eex:89
msgid "Warning" msgid "Warning"
msgstr "Attention" msgstr "Attention"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:54 #: lib/web/templates/email/event_updated.html.eex:54
msgid "Event has been cancelled" msgid "Event has been cancelled"
msgstr "L'événement a été annulé" msgstr "L'événement a été annulé"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:50 #: lib/web/templates/email/event_updated.html.eex:50
msgid "Event has been confirmed" msgid "Event has been confirmed"
msgstr "L'événement a été confirmé" msgstr "L'événement a été confirmé"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:52 #: lib/web/templates/email/event_updated.html.eex:52
msgid "Event status has been set as tentative" msgid "Event status has been set as tentative"
msgstr "Le statut de l'événement a été défini comme « à confirmer »" msgstr "Le statut de l'événement a été défini comme « à confirmer »"
#, elixir-format
#: lib/web/templates/email/email.html.eex:92 #: lib/web/templates/email/email.html.eex:92
msgid "%{b_start}Please do not use it in any real way%{b_end}" msgid "%{b_start}Please do not use it in any real way%{b_end}"
msgstr "%{b_start}Veuillez ne pas l'utiliser pour aucun évènement réel%{b_end}" msgstr "%{b_start}Veuillez ne pas l'utiliser pour aucun évènement réel%{b_end}"
#, elixir-format
#: lib/web/templates/email/report.html.eex:39 #: lib/web/templates/email/report.html.eex:39
msgid "Someone on %{instance} reported the following content." msgid "Someone on %{instance} reported the following content."
msgstr "Quelqu'un sur %{instance} a signalé le contenu suivant." msgstr "Quelqu'un sur %{instance} a signalé le contenu suivant."
#, elixir-format
#: lib/web/templates/email/email.text.eex:10 #: lib/web/templates/email/email.text.eex:10
msgid "In the meantime, please consider that the software is not (yet) finished. More information on our blog:" msgid "In the meantime, please consider that the software is not (yet) finished. More information on our blog:"
msgstr "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Plus d'informations sur notre blog." msgstr "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Plus d'informations sur notre blog."
#, elixir-format
#: lib/web/templates/email/email.text.eex:9 #: lib/web/templates/email/email.text.eex:9
msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of version 1 of the software in the first half of 2020." msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of version 1 of the software in the first half of 2020."
msgstr "Mobilizon est en cours de développement, nous ajouterons de nouvelles fonctionnalités à ce site lors de mises à jour régulières, jusqu'à la publication de la version 1 du logiciel au premier semestre 2020." msgstr "Mobilizon est en cours de développement, nous ajouterons de nouvelles fonctionnalités à ce site lors de mises à jour régulières, jusqu'à la publication de la version 1 du logiciel au premier semestre 2020."
#, elixir-format
#: lib/web/templates/email/email.text.eex:7 #: lib/web/templates/email/email.text.eex:7
msgid "Please do not use it in any real way" msgid "Please do not use it in any real way"
msgstr "Veuillez ne pas l'utiliser pour un cas réel" msgstr "Veuillez ne pas l'utiliser pour un cas réel"
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
msgid "Confirm my participation" msgid "Confirm my participation"
msgstr "" msgstr "Confirmer ma participation"
#, elixir-format
#: lib/web/email/participation.ex:113 #: lib/web/email/participation.ex:113
msgid "Confirm your participation to event %{title}" msgid "Confirm your participation to event %{title}"
msgstr "" msgstr "Confirmer ma participation à l'événement %{title}"
#, elixir-format #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:45 lib/web/templates/email/anonymous_participation_confirmation.text.eex:7
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:45
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:7
msgid "If you didn't request this email, you can simply ignore it." msgid "If you didn't request this email, you can simply ignore it."
msgstr "Si vous n'avez pas demandé ceci, merci d'ignorer cet email." msgstr "Si vous n'avez pas demandé ceci, merci d'ignorer cet email."
#, elixir-format #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:13 lib/web/templates/email/anonymous_participation_confirmation.text.eex:1
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:13
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:1
msgid "Participation confirmation" msgid "Participation confirmation"
msgstr "" msgstr "Confirmation de participation"
#, elixir-format
#: lib/web/templates/api/terms.html.eex:108 #: lib/web/templates/api/terms.html.eex:108
msgctxt "terms" msgctxt "terms"
msgid "An internal ID for your current selected identity" msgid "An internal ID for your current selected identity"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:107 #: lib/web/templates/api/terms.html.eex:107
msgctxt "terms" msgctxt "terms"
msgid "An internal user ID" msgid "An internal user ID"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:45 #: lib/web/templates/api/terms.html.eex:45
msgctxt "terms" msgctxt "terms"
msgid "Any of the information we collect from you may be used in the following ways:" msgid "Any of the information we collect from you may be used in the following ways:"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:4 #: lib/web/templates/api/terms.html.eex:4
msgctxt "terms" msgctxt "terms"
msgid "Basic account information" msgid "Basic account information"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:28 #: lib/web/templates/api/terms.html.eex:28
msgctxt "terms" msgctxt "terms"
msgid "Do not share any dangerous information over Mobilizon." msgid "Do not share any dangerous information over Mobilizon."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:126 #: lib/web/templates/api/terms.html.eex:126
msgctxt "terms" msgctxt "terms"
msgid "Do we disclose any information to outside parties?" msgid "Do we disclose any information to outside parties?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:101 #: lib/web/templates/api/terms.html.eex:101
msgctxt "terms" msgctxt "terms"
msgid "Do we use cookies?" msgid "Do we use cookies?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:59 #: lib/web/templates/api/terms.html.eex:59
msgctxt "terms" msgctxt "terms"
msgid "How do we protect your information?" msgid "How do we protect your information?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:32 #: lib/web/templates/api/terms.html.eex:32
msgctxt "terms" msgctxt "terms"
msgid "IPs and other metadata" msgid "IPs and other metadata"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:111 #: lib/web/templates/api/terms.html.eex:111
msgctxt "terms" msgctxt "terms"
msgid "If you delete these informations, you need to login again." msgid "If you delete these informations, you need to login again."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:113 #: lib/web/templates/api/terms.html.eex:113
msgctxt "terms" msgctxt "terms"
msgid "If you're not connected, we don't store any information on your device, unless you participate in an event\n anonymously. In that case we store the hash of the UUID and participation status in your browser so that we may\n display participation status. Deleting these informations will only stop displaying participation status in your\n browser." msgid ""
"If you're not connected, we don't store any information on your device, unless you participate in an event\n"
" anonymously. In that case we store the hash of the UUID and participation status in your browser so that we may\n"
" display participation status. Deleting these informations will only stop displaying participation status in your\n"
" browser."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:123 #: lib/web/templates/api/terms.html.eex:123
msgctxt "terms" msgctxt "terms"
msgid "Note: These informations are stored in your localStorage and not your cookies." msgid "Note: These informations are stored in your localStorage and not your cookies."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:18 #: lib/web/templates/api/terms.html.eex:18
msgctxt "terms" msgctxt "terms"
msgid "Published events and comments" msgid "Published events and comments"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:83 #: lib/web/templates/api/terms.html.eex:83
msgctxt "terms" msgctxt "terms"
msgid "Retain the IP addresses associated with registered users no more than 12 months." msgid "Retain the IP addresses associated with registered users no more than 12 months."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:109 #: lib/web/templates/api/terms.html.eex:109
msgctxt "terms" msgctxt "terms"
msgid "Tokens to authenticate you" msgid "Tokens to authenticate you"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:35 #: lib/web/templates/api/terms.html.eex:35
msgctxt "terms" msgctxt "terms"
msgid "We also may retain server logs which include the IP address of every request to our server." msgid "We also may retain server logs which include the IP address of every request to our server."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:5 #: lib/web/templates/api/terms.html.eex:5
msgctxt "terms" msgctxt "terms"
msgid "We collect information from you when you register on this server and gather data when you participate in the\n platform by reading, writing, and interacting with content shared here. If you register on this server, you will\n be asked to enter an e-mail address, a password and at least an username. Your e-mail address will be verified by\n an email containing a unique link. If that link is visited, we know that you control the e-mail address. You may\n also enter additional profile information such as a display name and biography, and upload a profile picture and\n header image. The username, display name, biography, profile picture and header image are always listed publicly.\n You may, however, visit this server without registering." msgid ""
"We collect information from you when you register on this server and gather data when you participate in the\n"
" platform by reading, writing, and interacting with content shared here. If you register on this server, you will\n"
" be asked to enter an e-mail address, a password and at least an username. Your e-mail address will be verified by\n"
" an email containing a unique link. If that link is visited, we know that you control the e-mail address. You may\n"
" also enter additional profile information such as a display name and biography, and upload a profile picture and\n"
" header image. The username, display name, biography, profile picture and header image are always listed publicly.\n"
" You may, however, visit this server without registering."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:130 #: lib/web/templates/api/terms.html.eex:130
msgctxt "terms" msgctxt "terms"
msgid "We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This\n does not include trusted third parties who assist us in operating our site, conducting our business, or servicing\n you, so long as those parties agree to keep this information confidential. We may also release your information\n when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or\n others rights, property, or safety." msgid ""
"We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This\n"
" does not include trusted third parties who assist us in operating our site, conducting our business, or servicing\n"
" you, so long as those parties agree to keep this information confidential. We may also release your information\n"
" when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or\n"
" others rights, property, or safety."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:62 #: lib/web/templates/api/terms.html.eex:62
msgctxt "terms" msgctxt "terms"
msgid "We implement a variety of security measures to maintain the safety of your personal information when you enter,\n submit, or access your personal information. Among other things, your browser session, as well as the traffic between\n your applications and the API, are secured with SSL/TLS, and your password is hashed using a strong one-way\n algorithm." msgid ""
"We implement a variety of security measures to maintain the safety of your personal information when you enter,\n"
" submit, or access your personal information. Among other things, your browser session, as well as the traffic between\n"
" your applications and the API, are secured with SSL/TLS, and your password is hashed using a strong one-way\n"
" algorithm."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:103 #: lib/web/templates/api/terms.html.eex:103
msgctxt "terms" msgctxt "terms"
msgid "We store the following information on your device when you connect:" msgid "We store the following information on your device when you connect:"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:72 #: lib/web/templates/api/terms.html.eex:72
msgctxt "terms" msgctxt "terms"
msgid "We will make a good faith effort to:" msgid "We will make a good faith effort to:"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:43 #: lib/web/templates/api/terms.html.eex:43
msgctxt "terms" msgctxt "terms"
msgid "What do we use your information for?" msgid "What do we use your information for?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:71 #: lib/web/templates/api/terms.html.eex:71
msgctxt "terms" msgctxt "terms"
msgid "What is our data retention policy?" msgid "What is our data retention policy?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:92 #: lib/web/templates/api/terms.html.eex:92
msgctxt "terms" msgctxt "terms"
msgid "You can request and download an archive of your content, including your posts, media attachments, profile picture,\n and header image." msgid ""
"You can request and download an archive of your content, including your posts, media attachments, profile picture,\n"
" and header image."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:100 #: lib/web/templates/api/terms.html.eex:100
msgctxt "terms" msgctxt "terms"
msgid "You may irreversibly delete your account at any time." msgid "You may irreversibly delete your account at any time."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:142 #: lib/web/templates/api/terms.html.eex:142
msgctxt "terms" msgctxt "terms"
msgid "Your content may be downloaded by other servers in the network. Your content is delivered to the servers\n following your instance, and direct messages are delivered to the servers of the recipients, in so far as these\n recipients reside on a different server than this one." msgid ""
"Your content may be downloaded by other servers in the network. Your content is delivered to the servers\n"
" following your instance, and direct messages are delivered to the servers of the recipients, in so far as these\n"
" recipients reside on a different server than this one."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:20 #: lib/web/templates/api/terms.html.eex:20
msgctxt "terms" msgctxt "terms"
msgid "Your events and comments are delivered to other instances that follow your own, meaning they are delivered to\n different servers and copies are stored there. When you delete events or comments, this is likewise delivered to\n these other instances. The action of joining an event is federated as well. Please keep in mind that the operators\n of the server and any receiving server may view such messages, and that recipients may screenshot, copy or\n otherwise re-share them." msgid ""
"Your events and comments are delivered to other instances that follow your own, meaning they are delivered to\n"
" different servers and copies are stored there. When you delete events or comments, this is likewise delivered to\n"
" these other instances. The action of joining an event is federated as well. Please keep in mind that the operators\n"
" of the server and any receiving server may view such messages, and that recipients may screenshot, copy or\n"
" otherwise re-share them."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:159 #: lib/web/templates/api/terms.html.eex:159
msgctxt "terms" msgctxt "terms"
msgid "Changes to our Privacy Policy" msgid "Changes to our Privacy Policy"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:154 #: lib/web/templates/api/terms.html.eex:154
msgctxt "terms" msgctxt "terms"
msgid "If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\">General Data Protection Regulation</a>) do not use this site." msgid "If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\">General Data Protection Regulation</a>) do not use this site."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:155 #: lib/web/templates/api/terms.html.eex:155
msgctxt "terms" msgctxt "terms"
msgid "If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection Act</a>) do not use this site." msgid "If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection Act</a>) do not use this site."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:161 #: lib/web/templates/api/terms.html.eex:161
msgctxt "terms" msgctxt "terms"
msgid "If we decide to change our privacy policy, we will post those changes on this page." msgid "If we decide to change our privacy policy, we will post those changes on this page."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:156 #: lib/web/templates/api/terms.html.eex:156
msgctxt "terms" msgctxt "terms"
msgid "Law requirements can be different if this server is in another jurisdiction." msgid "Law requirements can be different if this server is in another jurisdiction."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:163 #: lib/web/templates/api/terms.html.eex:163
msgctxt "terms" msgctxt "terms"
msgid "Originally adapted from the <a href=\"https://mastodon.social/terms\">Mastodon</a> and <a href=\"https://github.com/discourse/discourse\">Discourse</a> privacy policies." msgid "Originally adapted from the <a href=\"https://mastodon.social/terms\">Mastodon</a> and <a href=\"https://github.com/discourse/discourse\">Discourse</a> privacy policies."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:75 #: lib/web/templates/api/terms.html.eex:75
msgctxt "terms" msgctxt "terms"
msgid "Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more\n than 90 days." msgid ""
"Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more\n"
" than 90 days."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:152 #: lib/web/templates/api/terms.html.eex:152
msgctxt "terms" msgctxt "terms"
msgid "Site usage by children" msgid "Site usage by children"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:55 #: lib/web/templates/api/terms.html.eex:55
msgctxt "terms" msgctxt "terms"
msgid "The email address you provide may be used to send you information, updates and notifications about other people\n interacting with your content or sending you messages and to respond to inquiries, and/or other requests or\n questions." msgid ""
"The email address you provide may be used to send you information, updates and notifications about other people\n"
" interacting with your content or sending you messages and to respond to inquiries, and/or other requests or\n"
" questions."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:162 #: lib/web/templates/api/terms.html.eex:162
msgctxt "terms" msgctxt "terms"
msgid "This document is CC-BY-SA. It was last updated January 16, 2020." msgid "This document is CC-BY-SA. It was last updated January 16, 2020."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:53 #: lib/web/templates/api/terms.html.eex:53
msgctxt "terms" msgctxt "terms"
msgid "To aid moderation of the community, for example comparing your IP address with other known ones to determine ban\n evasion or other violations." msgid ""
"To aid moderation of the community, for example comparing your IP address with other known ones to determine ban\n"
" evasion or other violations."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:51 #: lib/web/templates/api/terms.html.eex:51
msgctxt "terms" msgctxt "terms"
msgid "To provide the core functionality of Mobilizon. Depending on this instance's policy you may only be able to\n interact with other people's content and post your own content if you are logged in." msgid ""
"To provide the core functionality of Mobilizon. Depending on this instance's policy you may only be able to\n"
" interact with other people's content and post your own content if you are logged in."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/api/terms.html.eex:1 #: lib/web/templates/api/terms.html.eex:1
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#: lib/web/templates/email/email_changed_new.html.eex:38 lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr "Confirmez le changement d'adresse email."
#: lib/web/templates/email/email_changed_new.html.eex:64 lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr "Si vous n'êtes pas à l'origine de ce changement d'adresse email, vous pouvez ignorer ce message. L'adresse email du compte Mobilizon ne sera pas modifiée tant que vous n'accédez pas au lien ci-dessus."
#: lib/web/templates/email/email_changed_old.html.eex:62 lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr "Si vous n'avez pas demandé à changer votre adresse email, il est probable que quelqu'un ait accédé à votre compte. Veuillez changer votre mot de passe immédiatement ou contacter l'administrateur du serveur si vous n'arrivez plus à vous contacter."
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr "Mobilizon sur %{instance}: confirmez votre adresse email"
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr "Mobilizon sur %{instance}: adresse email modifiée"
#: lib/web/templates/email/email_changed_old.html.eex:13 lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr "Nouvelle adresse email"
#: lib/web/templates/email/email_changed_old.html.eex:38 lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr "L'adresse email pour votre compte sur %{host} est en train d'être changée pour :"
#: lib/web/templates/email/email_changed_new.html.eex:13 lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr "Vérifier l'adresse email"

View File

@ -625,3 +625,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -622,3 +622,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -652,3 +652,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -646,3 +646,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "Quinas informacions reculem?" msgstr "Quinas informacions reculem?"
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -655,3 +655,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -622,3 +622,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -633,3 +633,49 @@ msgstr ""
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -14,633 +14,679 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.9.1\n" "X-Generator: Weblate 3.9.1\n"
#, elixir-format
#: lib/web/templates/email/password_reset.html.eex:48 #: lib/web/templates/email/password_reset.html.eex:48
#: lib/web/templates/email/password_reset.text.eex:12 #: lib/web/templates/email/password_reset.text.eex:12
#, elixir-format
msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one." msgid "If you didn't request this, please ignore this email. Your password won't change until you access the link below and create a new one."
msgstr "" msgstr ""
"Du kan ignorera det här meddelandet om du inte frågade efter det. Ditt " "Du kan ignorera det här meddelandet om du inte frågade efter det. Ditt "
"lösenord kommer inte ändras förrän du har öppnat länken nedan och skapat ett " "lösenord kommer inte ändras förrän du har öppnat länken nedan och skapat ett "
"nytt." "nytt."
#: lib/service/export/feed.ex:169
#, elixir-format #, elixir-format
#: lib/service/export/feed.ex:169
msgid "Feed for %{email} on Mobilizon" msgid "Feed for %{email} on Mobilizon"
msgstr "Flöde för %{email} på Mobilizon" msgstr "Flöde för %{email} på Mobilizon"
#, elixir-format
#: lib/web/templates/email/email.html.eex:155 #: lib/web/templates/email/email.html.eex:155
#: lib/web/templates/email/email.text.eex:16 #: lib/web/templates/email/email.text.eex:16
#, elixir-format
msgid "%{instance} is a Mobilizon server." msgid "%{instance} is a Mobilizon server."
msgstr "%{instance} är en Mobilizon-server." msgstr "%{instance} är en Mobilizon-server."
#: lib/web/templates/email/report.html.eex:41
#, elixir-format #, elixir-format
#: lib/web/templates/email/report.html.eex:41
msgid "%{reporter_name} (%{reporter_username}) reported the following content." msgid "%{reporter_name} (%{reporter_username}) reported the following content."
msgstr "%{reporter_name} (%{reporter_username}) har anmält följande innehåll." msgstr "%{reporter_name} (%{reporter_username}) har anmält följande innehåll."
#: lib/web/templates/email/report.html.eex:52
#, elixir-format #, elixir-format
#: lib/web/templates/email/report.html.eex:52
msgid "%{title} by %{creator}" msgid "%{title} by %{creator}"
msgstr "%{title} av %{creator}" msgstr "%{title} av %{creator}"
#: lib/web/templates/email/registration_confirmation.html.eex:58
#, elixir-format #, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:58
msgid "Activate my account" msgid "Activate my account"
msgstr "Aktivera mitt konto" msgstr "Aktivera mitt konto"
#, elixir-format
#: lib/web/templates/email/email.html.eex:124 #: lib/web/templates/email/email.html.eex:124
#: lib/web/templates/email/email.text.eex:14 #: lib/web/templates/email/email.text.eex:14
#, elixir-format
msgid "Ask the community on Framacolibri" msgid "Ask the community on Framacolibri"
msgstr "Fråga människorna på Framacolibri" msgstr "Fråga människorna på Framacolibri"
#, elixir-format
#: lib/web/templates/email/report.html.eex:66 #: lib/web/templates/email/report.html.eex:66
#: lib/web/templates/email/report.text.eex:13 #: lib/web/templates/email/report.text.eex:13
#, elixir-format
msgid "Comments" msgid "Comments"
msgstr "Kommentarer" msgstr "Kommentarer"
#, elixir-format
#: lib/web/templates/email/report.html.eex:50 #: lib/web/templates/email/report.html.eex:50
#: lib/web/templates/email/report.text.eex:6 #: lib/web/templates/email/report.text.eex:6
#, elixir-format
msgid "Event" msgid "Event"
msgstr "Evenemang" msgstr "Evenemang"
#: lib/web/templates/email/registration_confirmation.html.eex:45
#, elixir-format #, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:45
msgid "If you didn't request this, please ignore this email." msgid "If you didn't request this, please ignore this email."
msgstr "" msgstr ""
"Du kan strunta i det här meddelandet om det inte var du frågade efter det." "Du kan strunta i det här meddelandet om det inte var du frågade efter det."
#: lib/web/email/user.ex:48
#, elixir-format #, elixir-format
#: lib/web/email/user.ex:48
msgid "Instructions to reset your password on %{instance}" msgid "Instructions to reset your password on %{instance}"
msgstr "Instruktioner för att återställa ditt lösenord på %{instance}" msgstr "Instruktioner för att återställa ditt lösenord på %{instance}"
#: lib/web/templates/email/email.html.eex:156
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.html.eex:156
msgid "Learn more about Mobilizon." msgid "Learn more about Mobilizon."
msgstr "Läs mer om Mobilizon." msgstr "Läs mer om Mobilizon."
#: lib/web/templates/email/registration_confirmation.html.eex:13
#, elixir-format #, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:13
msgid "Nearly here!" msgid "Nearly here!"
msgstr "Snart framme!" msgstr "Snart framme!"
#, elixir-format
#: lib/web/templates/email/email.html.eex:121 #: lib/web/templates/email/email.html.eex:121
#: lib/web/templates/email/email.text.eex:12 #: lib/web/templates/email/email.text.eex:12
#, elixir-format
msgid "Need some help? Something not working properly?" msgid "Need some help? Something not working properly?"
msgstr "Behöver du hjälp? Är det något som krånglar?" msgstr "Behöver du hjälp? Är det något som krånglar?"
#: lib/web/templates/email/report.html.eex:13
#, elixir-format #, elixir-format
#: lib/web/templates/email/report.html.eex:13
msgid "New report on %{instance}" msgid "New report on %{instance}"
msgstr "Ny anmälan på %{instance}" msgstr "Ny anmälan på %{instance}"
#, elixir-format
#: lib/web/templates/email/report.html.eex:84 #: lib/web/templates/email/report.html.eex:84
#: lib/web/templates/email/report.text.eex:22 #: lib/web/templates/email/report.text.eex:22
#, elixir-format
msgid "Reason" msgid "Reason"
msgstr "Motivering" msgstr "Motivering"
#: lib/web/templates/email/password_reset.html.eex:61
#, elixir-format #, elixir-format
#: lib/web/templates/email/password_reset.html.eex:61
msgid "Reset Password" msgid "Reset Password"
msgstr "Återställ lösenordet" msgstr "Återställ lösenordet"
#: lib/web/templates/email/password_reset.html.eex:41
#, elixir-format #, elixir-format
#: lib/web/templates/email/password_reset.html.eex:41
msgid "Resetting your password is easy. Just press the button below and follow the instructions. We'll have you up and running in no time." msgid "Resetting your password is easy. Just press the button below and follow the instructions. We'll have you up and running in no time."
msgstr "" msgstr ""
"Det är enkelt att återställa ditt lösenord, klicka bara på knappen nedan och " "Det är enkelt att återställa ditt lösenord, klicka bara på knappen nedan och "
"följ instruktionerna. Du kommer vara igång igen på nolltid." "följ instruktionerna. Du kommer vara igång igen på nolltid."
#: lib/web/templates/email/password_reset.html.eex:13
#, elixir-format #, elixir-format
#: lib/web/templates/email/password_reset.html.eex:13
msgid "Trouble signing in?" msgid "Trouble signing in?"
msgstr "Svårt att logga in?" msgstr "Svårt att logga in?"
#: lib/web/templates/email/report.html.eex:104
#, elixir-format #, elixir-format
#: lib/web/templates/email/report.html.eex:104
msgid "View the report" msgid "View the report"
msgstr "Visa anmälan" msgstr "Visa anmälan"
#: lib/web/templates/email/registration_confirmation.html.eex:38
#, elixir-format #, elixir-format
#: lib/web/templates/email/registration_confirmation.html.eex:38
msgid "You created an account on %{host} with this email address. You are one click away from activating it." msgid "You created an account on %{host} with this email address. You are one click away from activating it."
msgstr "" msgstr ""
"Du har skapat ett konto på %{host} med den här e-postadressen. Nu återstår " "Du har skapat ett konto på %{host} med den här e-postadressen. Nu återstår "
"bara ett klick för att aktivera det." "bara ett klick för att aktivera det."
#: lib/web/email/user.ex:28
#, elixir-format #, elixir-format
#: lib/web/email/user.ex:28
msgid "Instructions to confirm your Mobilizon account on %{instance}" msgid "Instructions to confirm your Mobilizon account on %{instance}"
msgstr "Instruktioner för att bekräfta ditt Mobilizon-konto på %{instance}" msgstr "Instruktioner för att bekräfta ditt Mobilizon-konto på %{instance}"
#: lib/web/email/admin.ex:23
#, elixir-format #, elixir-format
#: lib/web/email/admin.ex:23
msgid "New report on Mobilizon instance %{instance}" msgid "New report on Mobilizon instance %{instance}"
msgstr "Ny anmälan på Mobilizon-instansen %{instance}" msgstr "Ny anmälan på Mobilizon-instansen %{instance}"
#: lib/web/templates/email/registration_confirmation.text.eex:1
#, elixir-format #, elixir-format
#: lib/web/templates/email/registration_confirmation.text.eex:1
msgid "Activate your account" msgid "Activate your account"
msgstr "Aktivera ditt konto" msgstr "Aktivera ditt konto"
#: lib/web/templates/email/event_participation_approved.html.eex:13
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_participation_approved.html.eex:13
msgid "All good!" msgid "All good!"
msgstr "Allt är i sin ordning!" msgstr "Allt är i sin ordning!"
#, elixir-format
#: lib/web/templates/email/event_participation_approved.html.eex:45 #: lib/web/templates/email/event_participation_approved.html.eex:45
#: lib/web/templates/email/event_participation_approved.text.eex:7 #: lib/web/templates/email/event_participation_approved.text.eex:7
#, elixir-format
msgid "An organizer just approved your participation. You're now going to this event!" msgid "An organizer just approved your participation. You're now going to this event!"
msgstr "" msgstr ""
"En organisatör godkände nyss ditt deltagande. Nu kan du delta i det här " "En organisatör godkände nyss ditt deltagande. Nu kan du delta i det här "
"evenemanget!" "evenemanget!"
#, elixir-format
#: lib/web/templates/email/event_participation_approved.html.eex:58 #: lib/web/templates/email/event_participation_approved.html.eex:58
#: lib/web/templates/email/event_updated.html.eex:101 #: lib/web/templates/email/event_updated.html.eex:101
#, elixir-format
msgid "Go to event page" msgid "Go to event page"
msgstr "Gå till evenemangets sida" msgstr "Gå till evenemangets sida"
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:70 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:70
#: lib/web/templates/email/event_participation_approved.html.eex:70 lib/web/templates/email/event_updated.html.eex:113 #: lib/web/templates/email/event_participation_approved.html.eex:70 lib/web/templates/email/event_updated.html.eex:113
#: lib/web/templates/email/event_updated.text.eex:21 #: lib/web/templates/email/event_updated.text.eex:21
#, elixir-format
msgid "If you need to cancel your participation, just access the event page through link above and click on the participation button." msgid "If you need to cancel your participation, just access the event page through link above and click on the participation button."
msgstr "" msgstr ""
"Om du behöver lämna återbud är det bara att gå till evenemangets sida, på " "Om du behöver lämna återbud är det bara att gå till evenemangets sida, på "
"länken ovan, och klicka på deltagande-knappen." "länken ovan, och klicka på deltagande-knappen."
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:11 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:11
#: lib/web/templates/email/event_participation_approved.text.eex:11 #: lib/web/templates/email/event_participation_approved.text.eex:11
#, elixir-format
msgid "If you need to cancel your participation, just access the previous link and click on the participation button." msgid "If you need to cancel your participation, just access the previous link and click on the participation button."
msgstr "" msgstr ""
"Om du behöver lämna återbud är det bara att gå till förra sidan och klicka " "Om du behöver lämna återbud är det bara att gå till förra sidan och klicka "
"på deltagande-knappen." "på deltagande-knappen."
#: lib/web/templates/email/email.text.eex:16
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.text.eex:16
msgid "Learn more about Mobilizon:" msgid "Learn more about Mobilizon:"
msgstr "Lär dig mer om Mobilizon:" msgstr "Lär dig mer om Mobilizon:"
#: lib/web/templates/email/report.text.eex:1
#, elixir-format #, elixir-format
#: lib/web/templates/email/report.text.eex:1
msgid "New report from %{reporter} on %{instance}" msgid "New report from %{reporter} on %{instance}"
msgstr "Ny anmälan från %{reporter} på %{instance}" msgstr "Ny anmälan från %{reporter} på %{instance}"
#: lib/web/templates/email/event_participation_approved.text.eex:1
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_participation_approved.text.eex:1
msgid "Participation approved" msgid "Participation approved"
msgstr "Ditt deltagande har godkänts" msgstr "Ditt deltagande har godkänts"
#: lib/web/templates/email/event_participation_rejected.text.eex:1
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_participation_rejected.text.eex:1
msgid "Participation rejected" msgid "Participation rejected"
msgstr "Ditt deltagande har inte godkänts" msgstr "Ditt deltagande har inte godkänts"
#: lib/web/templates/email/password_reset.text.eex:1
#, elixir-format #, elixir-format
#: lib/web/templates/email/password_reset.text.eex:1
msgid "Password reset" msgid "Password reset"
msgstr "Återställ lösenord" msgstr "Återställ lösenord"
#: lib/web/templates/email/password_reset.text.eex:7
#, elixir-format #, elixir-format
#: lib/web/templates/email/password_reset.text.eex:7
msgid "Resetting your password is easy. Just click the link below and follow the instructions. We'll have you up and running in no time." msgid "Resetting your password is easy. Just click the link below and follow the instructions. We'll have you up and running in no time."
msgstr "" msgstr ""
"Det är enkelt att återställa ditt lösenord, klicka bara på knappen nedan och " "Det är enkelt att återställa ditt lösenord, klicka bara på knappen nedan och "
"följ instruktionerna. Du kommer vara igång igen på nolltid." "följ instruktionerna. Du kommer vara igång igen på nolltid."
#: lib/web/templates/email/event_participation_rejected.html.eex:13
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_participation_rejected.html.eex:13
msgid "Sorry!" msgid "Sorry!"
msgstr "Vi beklagar!" msgstr "Vi beklagar!"
#, elixir-format
#: lib/web/templates/email/event_participation_rejected.html.eex:45 #: lib/web/templates/email/event_participation_rejected.html.eex:45
#: lib/web/templates/email/event_participation_rejected.text.eex:7 #: lib/web/templates/email/event_participation_rejected.text.eex:7
#, elixir-format
msgid "Unfortunately, the organizers rejected your participation." msgid "Unfortunately, the organizers rejected your participation."
msgstr "Organisatörerna har tyvärr gjort avslag på ditt deltagande." msgstr "Organisatörerna har tyvärr gjort avslag på ditt deltagande."
#: lib/web/templates/email/registration_confirmation.text.eex:5
#, elixir-format #, elixir-format
#: lib/web/templates/email/registration_confirmation.text.eex:5
msgid "You created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email." msgid "You created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email."
msgstr "" msgstr ""
"Du har skapat ett konto på %{host} med den här e-postadressen. Det återstår " "Du har skapat ett konto på %{host} med den här e-postadressen. Det återstår "
"bara ett klick för att aktivera den. Om det inte var du som gjorde det kan " "bara ett klick för att aktivera den. Om det inte var du som gjorde det kan "
"du strunta i det här meddelandet." "du strunta i det här meddelandet."
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:38 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:38
#: lib/web/templates/email/event_participation_approved.html.eex:38 #: lib/web/templates/email/event_participation_approved.html.eex:38
#, elixir-format
msgid "You requested to participate in event %{title}" msgid "You requested to participate in event %{title}"
msgstr "Du har bett om att få delta i evenemanget %{title}" msgstr "Du har bett om att få delta i evenemanget %{title}"
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:5 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:5
#: lib/web/templates/email/event_participation_approved.text.eex:5 lib/web/templates/email/event_participation_rejected.html.eex:38 #: lib/web/templates/email/event_participation_approved.text.eex:5 lib/web/templates/email/event_participation_rejected.html.eex:38
#: lib/web/templates/email/event_participation_rejected.text.eex:5 #: lib/web/templates/email/event_participation_rejected.text.eex:5
#, elixir-format
msgid "You requested to participate in event %{title}." msgid "You requested to participate in event %{title}."
msgstr "Du har bett om att få delta i evenemanget %{title}." msgstr "Du har bett om att få delta i evenemanget %{title}."
#: lib/web/email/participation.ex:91
#, elixir-format #, elixir-format
#: lib/web/email/participation.ex:91
msgid "Your participation to event %{title} has been approved" msgid "Your participation to event %{title} has been approved"
msgstr "Din förfrågan om att få delta i evenemanget %{title} har godkännts" msgstr "Din förfrågan om att få delta i evenemanget %{title} har godkännts"
#: lib/web/email/participation.ex:70
#, elixir-format #, elixir-format
#: lib/web/email/participation.ex:70
msgid "Your participation to event %{title} has been rejected" msgid "Your participation to event %{title} has been rejected"
msgstr "Din förfrågan om att få delta i evenemanget %{title} har fått avslag" msgstr "Din förfrågan om att få delta i evenemanget %{title} har fått avslag"
#: lib/web/templates/email/event_updated.html.eex:82
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:82
msgid "Ending of event" msgid "Ending of event"
msgstr "Evenemangets slut" msgstr "Evenemangets slut"
#: lib/web/email/event.ex:35
#, elixir-format #, elixir-format
#: lib/web/email/event.ex:35
msgid "Event %{title} has been updated" msgid "Event %{title} has been updated"
msgstr "Evenemanget %{title} har uppdaterats" msgstr "Evenemanget %{title} har uppdaterats"
#, elixir-format
#: lib/web/templates/email/event_updated.html.eex:13 #: lib/web/templates/email/event_updated.html.eex:13
#: lib/web/templates/email/event_updated.text.eex:1 #: lib/web/templates/email/event_updated.text.eex:1
#, elixir-format
msgid "Event updated!" msgid "Event updated!"
msgstr "Evenemang uppdaterat!" msgstr "Evenemang uppdaterat!"
#: lib/web/templates/email/event_updated.text.eex:16
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.text.eex:16
msgid "New date and time for ending of event: %{ends_on}" msgid "New date and time for ending of event: %{ends_on}"
msgstr "Nytt datum och tid för evenemangets slut: %{ends_on}" msgstr "Nytt datum och tid för evenemangets slut: %{ends_on}"
#: lib/web/templates/email/event_updated.text.eex:12
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.text.eex:12
msgid "New date and time for start of event: %{begins_on}" msgid "New date and time for start of event: %{begins_on}"
msgstr "Nytt datum och tid för evenemangets början: %{begins_on}" msgstr "Nytt datum och tid för evenemangets början: %{begins_on}"
#: lib/web/templates/email/event_updated.text.eex:8
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.text.eex:8
msgid "New title: %{title}" msgid "New title: %{title}"
msgstr "Ny titel: %{title}" msgstr "Ny titel: %{title}"
#: lib/web/templates/email/event_updated.html.eex:72
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:72
msgid "Start of event" msgid "Start of event"
msgstr "Evenemangets början" msgstr "Evenemangets början"
#: lib/web/templates/email/event_updated.text.eex:5
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.text.eex:5
msgid "The event %{title} was just updated" msgid "The event %{title} was just updated"
msgstr "Evenemanget %{title} uppdaterades nyss" msgstr "Evenemanget %{title} uppdaterades nyss"
#: lib/web/templates/email/event_updated.html.eex:38
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:38
msgid "The event %{title} was updated" msgid "The event %{title} was updated"
msgstr "Evenemanget %{title} uppdaterades" msgstr "Evenemanget %{title} uppdaterades"
#: lib/web/templates/email/event_updated.html.eex:62
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:62
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
#: lib/web/templates/email/event_updated.text.eex:19
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.text.eex:19
msgid "View the updated event on: %{link}" msgid "View the updated event on: %{link}"
msgstr "Visa det uppdaterade evenemanget på %{link}" msgstr "Visa det uppdaterade evenemanget på %{link}"
#, elixir-format
#: lib/web/templates/email/password_reset.html.eex:38 #: lib/web/templates/email/password_reset.html.eex:38
#: lib/web/templates/email/password_reset.text.eex:5 #: lib/web/templates/email/password_reset.text.eex:5
#, elixir-format
msgid "You requested a new password for your account on %{instance}." msgid "You requested a new password for your account on %{instance}."
msgstr "Du har bett om ett nytt lösenord för ditt konto på %{instance}." msgstr "Du har bett om ett nytt lösenord för ditt konto på %{instance}."
#: lib/web/templates/email/email.html.eex:95
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.html.eex:95
msgid "In the meantime, please consider that the software is not (yet) finished. More information %{a_start}on our blog%{a_end}." msgid "In the meantime, please consider that the software is not (yet) finished. More information %{a_start}on our blog%{a_end}."
msgstr "" msgstr ""
#: lib/web/templates/email/email.html.eex:94
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.html.eex:94
msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of %{b_start}version 1 of the software in the first half of 2020%{b_end}." msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of %{b_start}version 1 of the software in the first half of 2020%{b_end}."
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email.html.eex:91 #: lib/web/templates/email/email.html.eex:91
#: lib/web/templates/email/email.text.eex:6 #: lib/web/templates/email/email.text.eex:6
#, elixir-format
msgid "This is a demonstration site to test the beta version of Mobilizon." msgid "This is a demonstration site to test the beta version of Mobilizon."
msgstr "" msgstr ""
#: lib/web/templates/email/email.html.eex:89
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.html.eex:89
msgid "Warning" msgid "Warning"
msgstr "" msgstr ""
#: lib/web/templates/email/event_updated.html.eex:54
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:54
msgid "Event has been cancelled" msgid "Event has been cancelled"
msgstr "" msgstr ""
#: lib/web/templates/email/event_updated.html.eex:50
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:50
msgid "Event has been confirmed" msgid "Event has been confirmed"
msgstr "" msgstr ""
#: lib/web/templates/email/event_updated.html.eex:52
#, elixir-format #, elixir-format
#: lib/web/templates/email/event_updated.html.eex:52
msgid "Event status has been set as tentative" msgid "Event status has been set as tentative"
msgstr "" msgstr ""
#: lib/web/templates/email/email.html.eex:92
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.html.eex:92
msgid "%{b_start}Please do not use it in any real way%{b_end}" msgid "%{b_start}Please do not use it in any real way%{b_end}"
msgstr "" msgstr ""
#: lib/web/templates/email/report.html.eex:39
#, elixir-format #, elixir-format
#: lib/web/templates/email/report.html.eex:39
msgid "Someone on %{instance} reported the following content." msgid "Someone on %{instance} reported the following content."
msgstr "" msgstr ""
#: lib/web/templates/email/email.text.eex:10
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.text.eex:10
msgid "In the meantime, please consider that the software is not (yet) finished. More information on our blog:" msgid "In the meantime, please consider that the software is not (yet) finished. More information on our blog:"
msgstr "" msgstr ""
#: lib/web/templates/email/email.text.eex:9
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.text.eex:9
msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of version 1 of the software in the first half of 2020." msgid "Mobilizon is under development, we will add new features to this site during regular updates, until the release of version 1 of the software in the first half of 2020."
msgstr "" msgstr ""
#: lib/web/templates/email/email.text.eex:7
#, elixir-format #, elixir-format
#: lib/web/templates/email/email.text.eex:7
msgid "Please do not use it in any real way" msgid "Please do not use it in any real way"
msgstr "" msgstr ""
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
#, elixir-format #, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:58
msgid "Confirm my participation" msgid "Confirm my participation"
msgstr "" msgstr ""
#: lib/web/email/participation.ex:113
#, elixir-format #, elixir-format
#: lib/web/email/participation.ex:113
msgid "Confirm your participation to event %{title}" msgid "Confirm your participation to event %{title}"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:45 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:45
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:7 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:7
#, elixir-format
msgid "If you didn't request this email, you can simply ignore it." msgid "If you didn't request this email, you can simply ignore it."
msgstr "" msgstr ""
"Du kan strunta i det här meddelandet om det inte var du frågade efter det." "Du kan strunta i det här meddelandet om det inte var du frågade efter det."
#, elixir-format
#: lib/web/templates/email/anonymous_participation_confirmation.html.eex:13 #: lib/web/templates/email/anonymous_participation_confirmation.html.eex:13
#: lib/web/templates/email/anonymous_participation_confirmation.text.eex:1 #: lib/web/templates/email/anonymous_participation_confirmation.text.eex:1
#, elixir-format
msgid "Participation confirmation" msgid "Participation confirmation"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:108
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:108
msgctxt "terms" msgctxt "terms"
msgid "An internal ID for your current selected identity" msgid "An internal ID for your current selected identity"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:107
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:107
msgctxt "terms" msgctxt "terms"
msgid "An internal user ID" msgid "An internal user ID"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:45
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:45
msgctxt "terms" msgctxt "terms"
msgid "Any of the information we collect from you may be used in the following ways:" msgid "Any of the information we collect from you may be used in the following ways:"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:4
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:4
msgctxt "terms" msgctxt "terms"
msgid "Basic account information" msgid "Basic account information"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:28
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:28
msgctxt "terms" msgctxt "terms"
msgid "Do not share any dangerous information over Mobilizon." msgid "Do not share any dangerous information over Mobilizon."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:126
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:126
msgctxt "terms" msgctxt "terms"
msgid "Do we disclose any information to outside parties?" msgid "Do we disclose any information to outside parties?"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:101
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:101
msgctxt "terms" msgctxt "terms"
msgid "Do we use cookies?" msgid "Do we use cookies?"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:59
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:59
msgctxt "terms" msgctxt "terms"
msgid "How do we protect your information?" msgid "How do we protect your information?"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:32
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:32
msgctxt "terms" msgctxt "terms"
msgid "IPs and other metadata" msgid "IPs and other metadata"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:111
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:111
msgctxt "terms" msgctxt "terms"
msgid "If you delete these informations, you need to login again." msgid "If you delete these informations, you need to login again."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:113
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:113
msgctxt "terms" msgctxt "terms"
msgid "If you're not connected, we don't store any information on your device, unless you participate in an event\n anonymously. In that case we store the hash of the UUID and participation status in your browser so that we may\n display participation status. Deleting these informations will only stop displaying participation status in your\n browser." msgid "If you're not connected, we don't store any information on your device, unless you participate in an event\n anonymously. In that case we store the hash of the UUID and participation status in your browser so that we may\n display participation status. Deleting these informations will only stop displaying participation status in your\n browser."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:123
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:123
msgctxt "terms" msgctxt "terms"
msgid "Note: These informations are stored in your localStorage and not your cookies." msgid "Note: These informations are stored in your localStorage and not your cookies."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:18
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:18
msgctxt "terms" msgctxt "terms"
msgid "Published events and comments" msgid "Published events and comments"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:83
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:83
msgctxt "terms" msgctxt "terms"
msgid "Retain the IP addresses associated with registered users no more than 12 months." msgid "Retain the IP addresses associated with registered users no more than 12 months."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:109
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:109
msgctxt "terms" msgctxt "terms"
msgid "Tokens to authenticate you" msgid "Tokens to authenticate you"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:35
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:35
msgctxt "terms" msgctxt "terms"
msgid "We also may retain server logs which include the IP address of every request to our server." msgid "We also may retain server logs which include the IP address of every request to our server."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:5
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:5
msgctxt "terms" msgctxt "terms"
msgid "We collect information from you when you register on this server and gather data when you participate in the\n platform by reading, writing, and interacting with content shared here. If you register on this server, you will\n be asked to enter an e-mail address, a password and at least an username. Your e-mail address will be verified by\n an email containing a unique link. If that link is visited, we know that you control the e-mail address. You may\n also enter additional profile information such as a display name and biography, and upload a profile picture and\n header image. The username, display name, biography, profile picture and header image are always listed publicly.\n You may, however, visit this server without registering." msgid "We collect information from you when you register on this server and gather data when you participate in the\n platform by reading, writing, and interacting with content shared here. If you register on this server, you will\n be asked to enter an e-mail address, a password and at least an username. Your e-mail address will be verified by\n an email containing a unique link. If that link is visited, we know that you control the e-mail address. You may\n also enter additional profile information such as a display name and biography, and upload a profile picture and\n header image. The username, display name, biography, profile picture and header image are always listed publicly.\n You may, however, visit this server without registering."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:130
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:130
msgctxt "terms" msgctxt "terms"
msgid "We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This\n does not include trusted third parties who assist us in operating our site, conducting our business, or servicing\n you, so long as those parties agree to keep this information confidential. We may also release your information\n when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or\n others rights, property, or safety." msgid "We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This\n does not include trusted third parties who assist us in operating our site, conducting our business, or servicing\n you, so long as those parties agree to keep this information confidential. We may also release your information\n when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or\n others rights, property, or safety."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:62
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:62
msgctxt "terms" msgctxt "terms"
msgid "We implement a variety of security measures to maintain the safety of your personal information when you enter,\n submit, or access your personal information. Among other things, your browser session, as well as the traffic between\n your applications and the API, are secured with SSL/TLS, and your password is hashed using a strong one-way\n algorithm." msgid "We implement a variety of security measures to maintain the safety of your personal information when you enter,\n submit, or access your personal information. Among other things, your browser session, as well as the traffic between\n your applications and the API, are secured with SSL/TLS, and your password is hashed using a strong one-way\n algorithm."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:103
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:103
msgctxt "terms" msgctxt "terms"
msgid "We store the following information on your device when you connect:" msgid "We store the following information on your device when you connect:"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:72
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:72
msgctxt "terms" msgctxt "terms"
msgid "We will make a good faith effort to:" msgid "We will make a good faith effort to:"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:43
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:43
msgctxt "terms" msgctxt "terms"
msgid "What do we use your information for?" msgid "What do we use your information for?"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:71
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:71
msgctxt "terms" msgctxt "terms"
msgid "What is our data retention policy?" msgid "What is our data retention policy?"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:92
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:92
msgctxt "terms" msgctxt "terms"
msgid "You can request and download an archive of your content, including your posts, media attachments, profile picture,\n and header image." msgid "You can request and download an archive of your content, including your posts, media attachments, profile picture,\n and header image."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:100
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:100
msgctxt "terms" msgctxt "terms"
msgid "You may irreversibly delete your account at any time." msgid "You may irreversibly delete your account at any time."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:142
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:142
msgctxt "terms" msgctxt "terms"
msgid "Your content may be downloaded by other servers in the network. Your content is delivered to the servers\n following your instance, and direct messages are delivered to the servers of the recipients, in so far as these\n recipients reside on a different server than this one." msgid "Your content may be downloaded by other servers in the network. Your content is delivered to the servers\n following your instance, and direct messages are delivered to the servers of the recipients, in so far as these\n recipients reside on a different server than this one."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:20
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:20
msgctxt "terms" msgctxt "terms"
msgid "Your events and comments are delivered to other instances that follow your own, meaning they are delivered to\n different servers and copies are stored there. When you delete events or comments, this is likewise delivered to\n these other instances. The action of joining an event is federated as well. Please keep in mind that the operators\n of the server and any receiving server may view such messages, and that recipients may screenshot, copy or\n otherwise re-share them." msgid "Your events and comments are delivered to other instances that follow your own, meaning they are delivered to\n different servers and copies are stored there. When you delete events or comments, this is likewise delivered to\n these other instances. The action of joining an event is federated as well. Please keep in mind that the operators\n of the server and any receiving server may view such messages, and that recipients may screenshot, copy or\n otherwise re-share them."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:159
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:159
msgctxt "terms" msgctxt "terms"
msgid "Changes to our Privacy Policy" msgid "Changes to our Privacy Policy"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:154
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:154
msgctxt "terms" msgctxt "terms"
msgid "If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\">General Data Protection Regulation</a>) do not use this site." msgid "If this server is in the EU or the EEA: Our site, products and services are all directed to people who are at least 16 years old. If you are under the age of 16, per the requirements of the GDPR (<a href=\"https://en.wikipedia.org/wiki/General_Data_Protection_Regulation\">General Data Protection Regulation</a>) do not use this site."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:155
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:155
msgctxt "terms" msgctxt "terms"
msgid "If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection Act</a>) do not use this site." msgid "If this server is in the USA: Our site, products and services are all directed to people who are at least 13 years old. If you are under the age of 13, per the requirements of COPPA (<a href=\"https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act\">Children's Online Privacy Protection Act</a>) do not use this site."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:161
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:161
msgctxt "terms" msgctxt "terms"
msgid "If we decide to change our privacy policy, we will post those changes on this page." msgid "If we decide to change our privacy policy, we will post those changes on this page."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:156
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:156
msgctxt "terms" msgctxt "terms"
msgid "Law requirements can be different if this server is in another jurisdiction." msgid "Law requirements can be different if this server is in another jurisdiction."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:163
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:163
msgctxt "terms" msgctxt "terms"
msgid "Originally adapted from the <a href=\"https://mastodon.social/terms\">Mastodon</a> and <a href=\"https://github.com/discourse/discourse\">Discourse</a> privacy policies." msgid "Originally adapted from the <a href=\"https://mastodon.social/terms\">Mastodon</a> and <a href=\"https://github.com/discourse/discourse\">Discourse</a> privacy policies."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:75
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:75
msgctxt "terms" msgctxt "terms"
msgid "Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more\n than 90 days." msgid "Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more\n than 90 days."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:152
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:152
msgctxt "terms" msgctxt "terms"
msgid "Site usage by children" msgid "Site usage by children"
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:55
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:55
msgctxt "terms" msgctxt "terms"
msgid "The email address you provide may be used to send you information, updates and notifications about other people\n interacting with your content or sending you messages and to respond to inquiries, and/or other requests or\n questions." msgid "The email address you provide may be used to send you information, updates and notifications about other people\n interacting with your content or sending you messages and to respond to inquiries, and/or other requests or\n questions."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:162
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:162
msgctxt "terms" msgctxt "terms"
msgid "This document is CC-BY-SA. It was last updated January 16, 2020." msgid "This document is CC-BY-SA. It was last updated January 16, 2020."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:53
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:53
msgctxt "terms" msgctxt "terms"
msgid "To aid moderation of the community, for example comparing your IP address with other known ones to determine ban\n evasion or other violations." msgid "To aid moderation of the community, for example comparing your IP address with other known ones to determine ban\n evasion or other violations."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:51
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:51
msgctxt "terms" msgctxt "terms"
msgid "To provide the core functionality of Mobilizon. Depending on this instance's policy you may only be able to\n interact with other people's content and post your own content if you are logged in." msgid "To provide the core functionality of Mobilizon. Depending on this instance's policy you may only be able to\n interact with other people's content and post your own content if you are logged in."
msgstr "" msgstr ""
#: lib/web/templates/api/terms.html.eex:1
#, elixir-format #, elixir-format
#: lib/web/templates/api/terms.html.eex:1
msgctxt "terms" msgctxt "terms"
msgid "What information do we collect?" msgid "What information do we collect?"
msgstr "" msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:38
#: lib/web/templates/email/email_changed_new.text.eex:5
msgid "Confirm the new address to change your email."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:64
#: lib/web/templates/email/email_changed_new.text.eex:10
msgid "If this change wasn't initiated by you, please ignore this email. The email address for the Mobilizon account won't change until you access the link above."
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:9
msgid "If you did not ask to change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the server admin if you're locked out of your account."
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:175
msgid "Mobilizon on %{instance}: confirm your email address"
msgstr ""
#, elixir-format
#: lib/web/email/user.ex:152
msgid "Mobilizon on %{instance}: email changed"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:13
#: lib/web/templates/email/email_changed_old.text.eex:1
msgid "New email address"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:38
#: lib/web/templates/email/email_changed_old.text.eex:5
msgid "The email address for your account on %{host} is being changed to:"
msgstr ""
#, elixir-format
#: lib/web/templates/email/email_changed_new.html.eex:13
#: lib/web/templates/email/email_changed_new.html.eex:51 lib/web/templates/email/email_changed_new.text.eex:1
msgid "Verify email address"
msgstr ""

View File

@ -0,0 +1,9 @@
defmodule Mobilizon.Storage.Repo.Migrations.AddUnconfirmedEmailToUsersTable do
use Ecto.Migration
def change do
alter table(:users) do
add(:unconfirmed_email, :string)
end
end
end

View File

@ -1,5 +1,5 @@
# source: http://localhost:4000/api # source: http://localhost:4000/api
# timestamp: Fri Jan 24 2020 10:31:31 GMT+0100 (GMT+01:00) # timestamp: Thu Feb 13 2020 11:32:20 GMT+0100 (GMT+01:00)
schema { schema {
query: RootQueryType query: RootQueryType
@ -543,7 +543,7 @@ input EventOptionsInput {
""" """
Whether or not to allow anonymous participation (if the server allows it) Whether or not to allow anonymous participation (if the server allows it)
""" """
anonymousParticipation: Boolean anonymousParticipation: Boolean = false
"""The list of special attendees""" """The list of special attendees"""
attendees: [String] attendees: [String]
@ -1082,65 +1082,34 @@ enum ReportStatus {
} }
type RootMutationType { type RootMutationType {
"""Validate an user after registration""" saveAdminSettings(instanceDescription: String, instanceName: String, instanceTerms: String, instanceTermsType: InstanceTermsType, instanceTermsUrl: String, registrationsOpen: Boolean): AdminSettings
validateUser(token: String!): Login changeEmail(email: String!, password: String!): User
"""Confirm a participation""" """Create a comment"""
confirmParticipation(confirmationToken: String!): Participant createComment(actorId: ID!, eventId: ID, inReplyToCommentId: ID, text: String!): Comment
deleteReportNote(moderatorId: ID!, noteId: ID!): DeletedObject
"""Delete a feed token""" """Create an user"""
deleteFeedToken(token: String!): DeletedFeedToken createUser(email: String!, locale: String, password: String!): User
"""Add a relay subscription""" """Update an identity"""
addRelay(address: String!): Follower updatePerson(
"""Create a report"""
createReport(commentsIds: [ID] = [""], content: String, eventId: ID, forward: Boolean = false, reportedId: ID!, reporterId: ID!): Report
"""Update a report"""
updateReportStatus(moderatorId: ID!, reportId: ID!, status: ReportStatus!): Report
"""Delete a relay subscription"""
removeRelay(address: String!): Follower
deleteComment(actorId: ID!, commentId: ID!): Comment
"""Reject a relay subscription"""
rejectRelay(address: String!): Follower
"""Delete a group"""
deleteGroup(actorId: ID!, groupId: ID!): DeletedObject
"""Reset user password"""
resetPassword(locale: String = "en", password: String!, token: String!): Login
"""Join an event"""
joinEvent(actorId: ID!, email: String, eventId: ID!): Participant
"""Create a group"""
createGroup(
""" """
The avatar for the group, either as an object or directly the ID of an existing Picture The avatar for the profile, either as an object or directly the ID of an existing Picture
""" """
avatar: PictureInput avatar: PictureInput
""" """
The banner for the group, either as an object or directly the ID of an existing Picture The banner for the profile, either as an object or directly the ID of an existing Picture
""" """
banner: PictureInput banner: PictureInput
id: ID!
"""The identity that creates the group""" """The displayed name for this profile"""
creatorActorId: ID!
"""The displayed name for the group"""
name: String name: String
"""The name for the group""" """The summary for this profile"""
preferredUsername: String! summary: String
): Person
"""The summary for the group"""
summary: String = ""
): Group
"""Create an event""" """Create an event"""
createEvent( createEvent(
@ -1168,6 +1137,147 @@ type RootMutationType {
title: String! title: String!
visibility: EventVisibility = PUBLIC visibility: EventVisibility = PUBLIC
): Event ): Event
validateEmail(token: String!): User
"""Delete an event"""
deleteEvent(actorId: ID!, eventId: ID!): DeletedObject
"""Accept a participation"""
updateParticipation(id: ID!, moderatorActorId: ID!, role: ParticipantRoleEnum!): Participant
"""Leave an event"""
leaveEvent(actorId: ID!, eventId: ID!, token: String): DeletedParticipant
"""Delete an identity"""
deletePerson(id: ID!): Person
"""Refresh a token"""
refreshToken(refreshToken: String!): RefreshedToken
"""Validate an user after registration"""
validateUser(token: String!): Login
"""Upload a picture"""
uploadPicture(actorId: ID!, alt: String, file: Upload!, name: String!): Picture
"""Delete a feed token"""
deleteFeedToken(token: String!): DeletedFeedToken
"""Create a note on a report"""
createReportNote(content: String, moderatorId: ID!, reportId: ID!): ReportNote
"""Leave an event"""
leaveGroup(actorId: ID!, groupId: ID!): DeletedMember
"""Create a Feed Token"""
createFeedToken(actorId: ID): FeedToken
"""Send a link through email to reset user password"""
sendResetPassword(email: String!, locale: String): String
"""Delete a relay subscription"""
removeRelay(address: String!): Follower
"""Change default actor for user"""
changeDefaultActor(preferredUsername: String!): User
deleteReportNote(moderatorId: ID!, noteId: ID!): DeletedObject
"""Create a report"""
createReport(commentsIds: [ID] = [""], content: String, eventId: ID, forward: Boolean = false, reportedId: ID!, reporterId: ID!): Report
"""Register a first profile on registration"""
registerPerson(
"""
The avatar for the profile, either as an object or directly the ID of an existing Picture
"""
avatar: PictureInput
"""
The banner for the profile, either as an object or directly the ID of an existing Picture
"""
banner: PictureInput
"""The email from the user previously created"""
email: String!
"""The displayed name for the new profile"""
name: String = ""
preferredUsername: String!
"""The summary for the new profile"""
summary: String = ""
): Person
"""Delete a group"""
deleteGroup(actorId: ID!, groupId: ID!): DeletedObject
deleteAccount(password: String!): DeletedObject
"""Add a relay subscription"""
addRelay(address: String!): Follower
"""Reset user password"""
resetPassword(locale: String = "en", password: String!, token: String!): Login
"""Create a group"""
createGroup(
"""
The avatar for the group, either as an object or directly the ID of an existing Picture
"""
avatar: PictureInput
"""
The banner for the group, either as an object or directly the ID of an existing Picture
"""
banner: PictureInput
"""The identity that creates the group"""
creatorActorId: ID!
"""The displayed name for the group"""
name: String
"""The name for the group"""
preferredUsername: String!
"""The summary for the group"""
summary: String = ""
): Group
"""Confirm a participation"""
confirmParticipation(confirmationToken: String!): Participant
deleteComment(actorId: ID!, commentId: ID!): Comment
"""Join an event"""
joinEvent(actorId: ID!, email: String, eventId: ID!): Participant
"""Accept a relay subscription"""
acceptRelay(address: String!): Follower
"""Join a group"""
joinGroup(actorId: ID!, groupId: ID!): Member
"""Reject a relay subscription"""
rejectRelay(address: String!): Follower
"""Create a new person for user"""
createPerson(
"""
The avatar for the profile, either as an object or directly the ID of an existing Picture
"""
avatar: PictureInput
"""
The banner for the profile, either as an object or directly the ID of an existing Picture
"""
banner: PictureInput
"""The displayed name for the new profile"""
name: String = ""
preferredUsername: String!
"""The summary for the new profile"""
summary: String = ""
): Person
"""Update an event""" """Update an event"""
updateEvent( updateEvent(
@ -1196,123 +1306,17 @@ type RootMutationType {
visibility: EventVisibility = PUBLIC visibility: EventVisibility = PUBLIC
): Event ): Event
"""Accept a relay subscription"""
acceptRelay(address: String!): Follower
"""Leave an event"""
leaveGroup(actorId: ID!, groupId: ID!): DeletedMember
"""Delete an identity"""
deletePerson(id: ID!): Person
saveAdminSettings(instanceDescription: String, instanceName: String, instanceTerms: String, instanceTermsType: InstanceTermsType, instanceTermsUrl: String, registrationsOpen: Boolean): AdminSettings
"""Refresh a token"""
refreshToken(refreshToken: String!): RefreshedToken
"""Upload a picture"""
uploadPicture(actorId: ID!, alt: String, file: Upload!, name: String!): Picture
"""Login an user"""
login(email: String!, password: String!): Login
"""Send a link through email to reset user password"""
sendResetPassword(email: String!, locale: String): String
"""Create a comment"""
createComment(actorId: ID!, eventId: ID, inReplyToCommentId: ID, text: String!): Comment
"""Register a first profile on registration"""
registerPerson(
"""
The avatar for the profile, either as an object or directly the ID of an existing Picture
"""
avatar: PictureInput
"""
The banner for the profile, either as an object or directly the ID of an existing Picture
"""
banner: PictureInput
"""The email from the user previously created"""
email: String!
"""The displayed name for the new profile"""
name: String = ""
preferredUsername: String!
"""The summary for the new profile"""
summary: String = ""
): Person
"""Update an identity"""
updatePerson(
"""
The avatar for the profile, either as an object or directly the ID of an existing Picture
"""
avatar: PictureInput
"""
The banner for the profile, either as an object or directly the ID of an existing Picture
"""
banner: PictureInput
id: ID!
"""The displayed name for this profile"""
name: String
"""The summary for this profile"""
summary: String
): Person
"""Delete an event"""
deleteEvent(actorId: ID!, eventId: ID!): DeletedObject
"""Join a group"""
joinGroup(actorId: ID!, groupId: ID!): Member
"""Change default actor for user"""
changeDefaultActor(preferredUsername: String!): User
"""Create an user"""
createUser(email: String!, locale: String, password: String!): User
"""Create a new person for user"""
createPerson(
"""
The avatar for the profile, either as an object or directly the ID of an existing Picture
"""
avatar: PictureInput
"""
The banner for the profile, either as an object or directly the ID of an existing Picture
"""
banner: PictureInput
"""The displayed name for the new profile"""
name: String = ""
preferredUsername: String!
"""The summary for the new profile"""
summary: String = ""
): Person
"""Create a note on a report"""
createReportNote(content: String, moderatorId: ID!, reportId: ID!): ReportNote
"""Change an user password""" """Change an user password"""
changePassword(newPassword: String!, oldPassword: String!): User changePassword(newPassword: String!, oldPassword: String!): User
"""Update a report"""
updateReportStatus(moderatorId: ID!, reportId: ID!, status: ReportStatus!): Report
"""Resend registration confirmation token""" """Resend registration confirmation token"""
resendConfirmationEmail(email: String!, locale: String): String resendConfirmationEmail(email: String!, locale: String): String
"""Leave an event""" """Login an user"""
leaveEvent(actorId: ID!, eventId: ID!, token: String): DeletedParticipant login(email: String!, password: String!): Login
"""Accept a participation"""
updateParticipation(id: ID!, moderatorActorId: ID!, role: ParticipantRoleEnum!): Participant
"""Create a Feed Token"""
createFeedToken(actorId: ID): FeedToken
} }
""" """

View File

@ -1,17 +1,57 @@
defmodule Mobilizon.GraphQL.Resolvers.UserTest do defmodule Mobilizon.GraphQL.Resolvers.UserTest do
use Mobilizon.Web.ConnCase use Mobilizon.Web.ConnCase
use Bamboo.Test use Bamboo.Test
use Oban.Testing, repo: Mobilizon.Storage.Repo
import Mobilizon.Factory import Mobilizon.Factory
alias Mobilizon.{Actors, Config, Users} alias Mobilizon.{Actors, Config, Events, Users}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.GraphQL.AbsintheHelpers alias Mobilizon.GraphQL.AbsintheHelpers
alias Mobilizon.Web.Email alias Mobilizon.Web.Email
@change_email_mutation """
mutation ChangeEmail($email: String!, $password: String!) {
changeEmail(email: $email, password: $password) {
id
}
}
"""
@login_mutation """
mutation Login($email: String!, $password: String!) {
login(email: $email, password: $password) {
accessToken,
refreshToken,
user {
id
}
}
}
"""
@validate_email_mutation """
mutation ValidateEmail($token: String!) {
validateEmail(
token: $token
) {
id
}
}
"""
@delete_user_account_mutation """
mutation DeleteAccount($password: String!) {
deleteAccount (password: $password) {
id
}
}
"""
@valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"} @valid_actor_params %{email: "test@test.tld", password: "testest", username: "test"}
@valid_single_actor_params %{preferred_username: "test2", keys: "yolo"} @valid_single_actor_params %{preferred_username: "test2", keys: "yolo"}
@ -1187,4 +1227,260 @@ defmodule Mobilizon.GraphQL.Resolvers.UserTest do
"You need to be logged-in to change your password" "You need to be logged-in to change your password"
end end
end end
describe "Resolver: Change email for an user" do
@old_email "old@domain.tld"
@new_email "new@domain.tld"
@password "p4ssw0rd"
test "change_email/3 with valid email", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @old_email, password: @password})
# Hammer time !
{:ok, %User{} = _user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> AbsintheHelpers.graphql_query(
query: @login_mutation,
variables: %{email: @old_email, password: @password}
)
login = res["data"]["login"]
assert Map.has_key?(login, "accessToken") && not is_nil(login["accessToken"])
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @change_email_mutation,
variables: %{email: @new_email, password: @password}
)
assert res["errors"] == nil
assert res["data"]["changeEmail"]["id"] == to_string(user.id)
user = Users.get_user!(user.id)
assert user.email == @old_email
assert user.unconfirmed_email == @new_email
assert_delivered_email(Email.User.send_email_reset_old_email(user))
assert_delivered_email(Email.User.send_email_reset_new_email(user))
conn
|> AbsintheHelpers.graphql_query(
query: @validate_email_mutation,
variables: %{token: user.confirmation_token}
)
user = Users.get_user!(user.id)
assert user.email == @new_email
assert user.unconfirmed_email == nil
end
test "change_email/3 with invalid password", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @old_email, password: @password})
# Hammer time !
{:ok, %User{} = _user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @change_email_mutation,
variables: %{email: @new_email, password: "invalid_password"}
)
assert hd(res["errors"])["message"] == "The password provided is invalid"
end
test "change_email/3 with same email", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @old_email, password: @password})
# Hammer time !
{:ok, %User{} = _user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @change_email_mutation,
variables: %{email: @old_email, password: @password}
)
assert hd(res["errors"])["message"] == "The new email must be different"
end
test "change_email/3 with invalid email", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @old_email, password: @password})
# Hammer time !
{:ok, %User{} = _user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @change_email_mutation,
variables: %{email: "invalid email", password: @password}
)
assert hd(res["errors"])["message"] == "The new email doesn't seem to be valid"
end
test "change_password/3 without being authenticated", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @old_email, password: @password})
# Hammer time !
{:ok, %User{} = _user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> AbsintheHelpers.graphql_query(
query: @change_email_mutation,
variables: %{email: @new_email, password: @password}
)
assert hd(res["errors"])["message"] ==
"You need to be logged-in to change your email"
end
end
describe "Resolver: User deletes it's account" do
@email "mail@domain.tld"
@password "p4ssw0rd"
test "delete_account/3 with valid password", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @email, password: @password})
# Hammer time !
{:ok, %User{} = user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
%Actor{} = actor1 = insert(:actor, user: user)
%Actor{} = actor2 = insert(:actor, user: user)
%Event{id: event_id} = event = insert(:event, organizer_actor: actor1)
%Participant{id: participant_id} =
insert(:participant, event: event, actor: actor2, role: :participant)
%Comment{id: comment_id} = insert(:comment, actor: actor2, event: event)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @delete_user_account_mutation,
variables: %{password: @password}
)
assert res["data"]["deleteAccount"]["id"] == to_string(user.id)
assert [
%Oban.Job{args: %{"actor_id" => actor2_id, "op" => "delete_actor"}},
%Oban.Job{args: %{"actor_id" => actor1_id, "op" => "delete_actor"}}
] = all_enqueued(queue: :background)
assert MapSet.new([actor1.id, actor2.id]) == MapSet.new([actor1_id, actor2_id])
assert_raise Ecto.NoResultsError, fn ->
Users.get_user!(user.id)
end
assert %{success: 2, failure: 0} == Oban.drain_queue(:background)
assert_raise Ecto.NoResultsError, fn ->
Events.get_event!(event_id)
end
assert_raise Ecto.NoResultsError, fn ->
Events.get_comment!(comment_id)
end
# Actors are not deleted but emptied (to keep the username reserved)
actor1 = Actors.get_actor!(actor1_id)
assert actor1.suspended
assert is_nil(actor1.name)
actor2 = Actors.get_actor!(actor2_id)
assert actor2.suspended
assert is_nil(actor2.name)
assert is_nil(Events.get_participant(participant_id))
end
test "delete_account/3 with invalid password", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @email, password: @password})
# Hammer time !
{:ok, %User{} = user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @delete_user_account_mutation,
variables: %{password: "invalid password"}
)
assert hd(res["errors"])["message"] == "The password provided is invalid"
end
test "delete_account/3 without being authenticated", %{conn: conn} do
{:ok, %User{} = user} = Users.register(%{email: @email, password: @password})
# Hammer time !
{:ok, %User{} = _user} =
Users.update_user(user, %{
confirmed_at: Timex.shift(user.confirmation_sent_at, hours: -3),
confirmation_sent_at: nil,
confirmation_token: nil
})
res =
conn
|> AbsintheHelpers.graphql_query(
query: @delete_user_account_mutation,
variables: %{password: "invalid password"}
)
assert hd(res["errors"])["message"] ==
"You need to be logged-in to delete your account"
end
end
end end