đ Fixes after PO review #324 #466 #513
jump to
@@ -4,9 +4,17 @@ "header": "<img src='https://app.caroster.io/uploads/Caroster_logo1_cddd3057fc.png?updated_at=2022-09-12T08:11:11.735Z' width='100%' alt='Caroster'/>",
"footer": "---\nđ You also think Caroster is awesome? Keep it free and support us with a donation!\n\nđ [Open collective](https://opencollective.com/caroster)\n\n<center><a href='https://caroster.io'>https://caroster.io</a></center>" }, "notifications": { + "ConfirmEmail": { + "title": "Please confirm your email address", + "content": "## Welcome on Caroster !\nPlease confirm your account by clicking on this link:\n\n[<%= confirmationLink %>](<%= confirmationLink %>)" + }, "NewTrip": { "title": "<%= event.name %> - A new trip is available", "content": "## New trip is available for \"<%= event.name %>\"\n\n**Car: <%= travel.vehicleName %>**\nCount of seats: <%= travel.seats %>\nDeparture location: <%= travel.meeting %>\nInformation: <%= travel.details %>.\n\n[Book my seat](<%= host %>/e/<%= event.uuid %>).\n\nYou are receiving this email because you are on the waiting list to find a carpool spot in this event." + }, + "NewTripAlert": { + "title": "<%= event.name %> - A new trip is available", + "content": "## New trip is available for \"<%= event.name %>\"\n\n**Car: <%= travel.vehicleName %>**\nCount of seats: <%= travel.seats %>\nDeparture location: <%= travel.meeting %>\nInformation: <%= travel.details %>.\n\n[Book my seat](<%= host %>/e/<%= event.uuid %>).\n\nYou are receiving this email because you've enabled alerts in this event." }, "DeletedTrip": { "title": "<%= event.name %> - Trip removed",
@@ -4,9 +4,17 @@ "header": "<img src='https://app.caroster.io/uploads/Caroster_logo1_cddd3057fc.png?updated_at=2022-09-12T08:11:11.735Z' width='100%' alt='Caroster'/>",
"footer": "---\nđ Vous pensez aussi que Caroster est gĂ©nial ? Aidez-nous Ă le maintenir libre et gratuit en faisant une donation !\n\nđ [Open collective](https://opencollective.com/caroster)\n\n<center><a href='https://caroster.io'>https://caroster.io</a></center>" }, "notifications": { + "ConfirmEmail": { + "title": "Merci de confirmer votre adresse email", + "content": "## Bienvenue sur Caroster !\nMerci de confirmer votre compte en cliquant sur le lien ci-dessous:\n\n[<%= confirmationLink %>](<%= confirmationLink %>)" + }, "NewTrip": { "title": "<%= event.name %> - Nouveau trajet disponible", - "content": "## Nouveau trajet pour \"<%= event.name %>\"\n\n**Voiture: <%= travel.vehicleName %>**\nNombre de places: <%= travel.seats %>\nLieu de dĂ©part: <%= travel.meeting %>\nInformations: <%= travel.details %>.\n\n[RĂ©server ma place](<%= host %>/e/<%= event.uuid %>).\n\nVous recevez cet e-mail, car vous ĂȘtes inscrit en liste d'attente pour trouver une place de covoiturage dans cet Ă©vĂ©nement." + "content": "## Nouveau trajet pour \"<%= event.name %>\"\n\n**Voiture: <%= travel.vehicleName %>**\nNombre de places: <%= travel.seats %>\nLieu de dĂ©part: <%= travel.meeting %>\nInformations: <%= travel.details %>.\n\n[RĂ©server ma place](<%= host %>/e/<%= event.uuid %>).\n\nVous recevez cet e-mail car vous ĂȘtes inscrit en liste d'attente pour trouver une place de covoiturage dans cet Ă©vĂ©nement." + }, + "NewTripAlert": { + "title": "<%= event.name %> - Nouveau trajet disponible", + "content": "## Nouveau trajet pour \"<%= event.name %>\"\n\n**Voiture: <%= travel.vehicleName %>**\nNombre de places: <%= travel.seats %>\nLieu de dĂ©part: <%= travel.meeting %>\nInformations: <%= travel.details %>.\n\n[RĂ©server ma place](<%= host %>/e/<%= event.uuid %>).\n\nVous recevez cet e-mail car vous avez configurĂ© une alerte de trajet Ă proximitĂ© pour cet Ă©vĂ©nement." }, "DeletedTrip": { "title": "<%= event.name %> - Trajet supprimĂ©",
@@ -84,7 +84,7 @@ const mdFooter = locales?.[lang]?.template.footer;
const htmlContent = await marked.parse(mdContent, { breaks: true }); const htmlHeader = await marked.parse(mdHeader, { breaks: true }); const htmlFooter = await marked.parse(mdFooter, { breaks: true }); - const html = `${getHTMLMeta()}<main>${htmlHeader}${htmlContent}${htmlFooter}</main>`; + const html = `${getHTMLMeta()}<header>${htmlHeader}</header><main>${htmlContent}${htmlFooter}</main>`; return { subject,
@@ -3,6 +3,13 @@ <style type="text/css">
body { font-family: sans; } + header { + text-align: center; + } + header img { + width: 20rem; + max-width: 100%; + } main { max-width: 40rem; margin: 0 auto;
@@ -17,6 +17,7 @@ "type": "enumeration",
"enum": [ "NewPassengerInYourTrip", "NewTrip", + "NewTripAlert", "DeletedTrip", "DeletedYourTrip", "DeletedFromTrip",
@@ -49,7 +49,7 @@ `Create trip alert notification for user ${tripAlert.user.id}`
); strapi.entityService.create("api::notification.notification", { data: { - type: "NewTrip", + type: "NewTripAlert", event: eventId, user: tripAlert.user.id, payload: { travel },
@@ -0,0 +1,32 @@
+import crypto from "crypto"; +import urlJoin from "url-join"; +import { getAbsoluteServerUrl, sanitize } from "@strapi/utils"; + +export default async (user) => { + const userSchema = strapi.getModel("plugin::users-permissions.user"); + + const confirmationToken = crypto.randomBytes(20).toString("hex"); + strapi.entityService.update("plugin::users-permissions.user", user.id, { + data: { confirmationToken }, + populate: ["role"], + }); + + const sanitizedUserInfo = await sanitize.sanitizers.defaultSanitizeOutput( + userSchema, + user + ); + const apiPrefix = strapi.config.get("api.rest.prefix"); + const url = urlJoin( + getAbsoluteServerUrl(strapi.config), + apiPrefix, + "/auth/email-confirmation" + ); + const confirmationLink = `${url}?confirmation=${confirmationToken}`; + await strapi + .service("api::email.email") + .sendEmailNotif(user.email, "ConfirmEmail", user.lang, { + confirmationToken, + confirmationLink, + user: sanitizedUserInfo, + }); +};
@@ -0,0 +1,13 @@
+import sendConfirmationEmail from "./services/sendConfirmationEmail"; + +export default (plugin) => { + const userServices = plugin.services.user; + plugin.services.user = (params) => { + const services = userServices(params); + return { + ...services, + sendConfirmationEmail, + }; + }; + return plugin; +};
@@ -964,6 +964,7 @@ type: Attribute.Enumeration<
[ 'NewPassengerInYourTrip', 'NewTrip', + 'NewTripAlert', 'DeletedTrip', 'DeletedYourTrip', 'DeletedFromTrip',
@@ -1,5 +1,4 @@
import {useRouter} from 'next/router'; -import { styled } from '@mui/material/styles'; import Container from '@mui/material/Container'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions';@@ -8,29 +7,12 @@ import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button'; import {useTranslation} from 'react-i18next'; -const PREFIX = 'DashboardEmpty'; - -const classes = { - container: `${PREFIX}-container` -}; - -const StyledContainer = styled(Container)(( - { - theme - } -) => ({ - [`&.${classes.container}`]: { - paddingTop: theme.spacing(8), - } -})); - const DashboardEmpty = () => { const {t} = useTranslation(); const router = useRouter(); - return ( - <StyledContainer maxWidth="sm" className={classes.container}> + <Container maxWidth="sm" sx={{pt: 8}}> <Card> <CardContent> <Typography gutterBottom variant="h5" component="h1">@@ -46,7 +28,7 @@ />
</CardContent> <CardActions> <Button - onClick={() => router.push('/')} + onClick={() => router.push('/new')} variant="contained" color="primary" >@@ -54,7 +36,7 @@ {t('dashboard.noEvent.create_event')}
</Button> </CardActions> </Card> - </StyledContainer> + </Container> ); };
@@ -131,6 +131,7 @@ "notifications.markAllRead": "Mark all in read",
"notifications.content": "No notification", "notification.type.NewPassengerInYourTrip.content": "A passenger has been added to your trip.", "notification.type.NewTrip.content": "A new trip close to you is available.", + "notification.type.NewTripAlert.content": "A new trip close to you is available.", "notification.type.DeletedTrip.content": "A trip has been removed.", "notification.type.DeletedYourTrip.content": "Your trip has been removed by an event administrator", "notification.type.AddedAsAdmin.content": "You have been promoted as administrator to the event.",@@ -262,7 +263,7 @@ "travel.passengers.add_me": "Add myself",
"travel.passengers.registered": "Assigned", "travel.passengers.add_someone": "Add someone", "travel.passengers.remove": "Remove", - "travel.passengers.removed": "Passenger removed from the car" , + "travel.passengers.removed": "Passenger removed from the car", "travel.passengers.add_to_car": "Add to car", "travel.passengers.add_to_travel": "Add passenger", "travel.passengers.add_to_waitingList": "Add to waiting list",
@@ -131,6 +131,7 @@ "notifications.markAllRead": "Tout marquer en lu",
"notifications.content": "Aucune notification", "notification.type.NewPassengerInYourTrip.content": "Un passager a été ajouté à votre trajet.", "notification.type.NewTrip.content": "Un nouveau trajet proche de chez vous est disponible.", + "notification.type.NewTripAlert.content": "Un nouveau trajet proche de chez vous est disponible.", "notification.type.DeletedTrip.content": "Un trajet a été supprimée.", "notification.type.DeletedYourTrip.content": "Votre trajet a été supprimé par un administrateur de l'événement.", "notification.type.AddedAsAdmin.content": "Vous avez été promu administrateur.",
@@ -119,6 +119,7 @@ "notifications.markAllRead": "",
"notifications.content": "", "notification.type.NewPassengerInYourTrip.content": "", "notification.type.NewTrip.content": "", + "notification.type.NewTripAlert.content": "", "notification.type.DeletedTrip.content": "", "notification.type.DeletedYourTrip.content": "", "notification.type.DeletedFromTrip.content": "",
@@ -122,6 +122,7 @@ "notifications.markAllRead": "",
"notifications.content": "", "notification.type.NewPassengerInYourTrip.content": "", "notification.type.NewTrip.content": "", + "notification.type.NewTripAlert.content": "", "notification.type.DeletedTrip.content": "", "notification.type.DeletedYourTrip.content": "", "notification.type.DeletedFromTrip.content": "",
@@ -119,6 +119,7 @@ "notifications.markAllRead": "",
"notifications.content": "", "notification.type.NewPassengerInYourTrip.content": "", "notification.type.NewTrip.content": "", + "notification.type.NewTripAlert.content": "", "notification.type.DeletedTrip.content": "", "notification.type.DeletedYourTrip.content": "", "notification.type.DeletedFromTrip.content": "",