Skip to content

Commit

Permalink
Send email to all admins when a new user has registered
Browse files Browse the repository at this point in the history
  • Loading branch information
floscher committed Jun 25, 2024
1 parent 682104b commit e3aab9b
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 10 deletions.
2 changes: 1 addition & 1 deletion client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
</div>
</nav>

<RouterView :userPermissions="loggedInUserInfo?.permissions" />
<RouterView :userPermissions="loggedInUserInfo?.permissions ?? DEFAULT_ROLE" />
</div>
<footer class="page-footer">
<div class="container">
Expand Down
5 changes: 3 additions & 2 deletions client/src/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"not-available": {
"title": "Post nicht vorhanden",
"message": "Der Post ist nicht verfügbar oder wurde gelöscht. Sie können mit dem Button zur Startseite zurück, oder nutzen sie die Suchfunktion um einen bestimmten Post zu finden."
}
}
}
},
"admin": {
Expand Down Expand Up @@ -105,7 +105,8 @@
"email": "E-mail",
"username": "Benutzername",
"fullname": "Dein Name"
}
},
"username-requirements": "Der Benutzername muss zwischen {min} und {max} Zeichen lang sein (ist {length} Zeichen lang) und darf nur aus den Buchstaben a-z/A-Z, den Zahlen 0-9 und den Zeichen ._- bestehen."
},
"user_not_found": "Benutzer nicht gefunden."
}
Expand Down
5 changes: 3 additions & 2 deletions client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@
"email": "Email",
"username": "Username",
"fullname": "Your name"
}
},
"username-requirements": "The username must be between 3 and 32 characters long and can only consist of letters a-z/A-Z, digits 0-9 and characters ._-"
},
"user_not_found": "User not found."
}
}
}
2 changes: 1 addition & 1 deletion client/src/util/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export class PostEndpoints {

static async findPosts(pageIndex: number, itemsPerPage = 12, search: string | undefined = undefined, operator: "and" | "or" = "and") {
return callServer<void, JsonMimeType, { data: [PublicPost[], number | null] }>(
`/api/posts/page/${pageIndex}/count/${itemsPerPage}${search ? `/search/${encodeURIComponent(search)}/operator/${operator}` : ""}###`,
`/api/posts/page/${pageIndex}/count/${itemsPerPage}${search ? `/search/${encodeURIComponent(search)}/operator/${operator}` : ""}`,
"GET",
"application/json",
null,
Expand Down
8 changes: 5 additions & 3 deletions server/src/routes/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
OAuthUserInfoDto,
UserInfoOAuthToken,
} from "@fumix/fu-blog-common";
import { sendNotificationEmailAboutNewRegistration } from "../service/email-service.js";
import express, { Request, Response, Router } from "express";
import fetch from "node-fetch";
import { BaseClient, Issuer, TokenSet } from "openid-client";
Expand Down Expand Up @@ -232,9 +233,10 @@ router.post("/userinfo/register", async (req, res, next) => {
oauthId: oauthUserId,
user,
};
await mgr
.insert(OAuthAccountEntity, [oauthAccount])
.then((it) => logger.info("New OAuth account created: " + JSON.stringify(oauthAccount)));
await mgr.insert(OAuthAccountEntity, [oauthAccount]).then((it) => {
sendNotificationEmailAboutNewRegistration(oauthAccount.user.username);
logger.info("New OAuth account created: " + JSON.stringify(oauthAccount));
});
})
.then(async () => {
const result: OAuthUserInfoDto = {
Expand Down
2 changes: 1 addition & 1 deletion server/src/routes/posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
NewPostRequestDto,
PostRequestDto,
} from "@fumix/fu-blog-common";
import logger from "@server/logger.js";
import logger from "../logger.js";
import express, { NextFunction, Request, Response, Router } from "express";
import { In } from "typeorm";
import { AppDataSource } from "../data-source.js";
Expand Down
56 changes: 56 additions & 0 deletions server/src/service/email-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import console from "console";
import { createTransport } from "nodemailer";
import { AppDataSource } from "../data-source.js";
import { UserEntity } from "../entity/User.entity.js";
import logger from "../logger.js";
import { ClientSettings, EmailSettings } from "../settings.js";

export async function sendNotificationEmailAboutNewRegistration(newUsername: string) {
const admin_emails = await AppDataSource.manager
.getRepository(UserEntity)
.createQueryBuilder("find all admins")
.where("roles @> :role", { role: ["ADMIN"] }) // https://www.postgresql.org/docs/16/functions-array.html#ARRAY-OPERATORS-TABLE
.getMany()
.then((users) => {
console.log("Found users", users);
return users.map((user) => user.email);
})
.catch((e) => {
console.error("Failed to get admins", e);
return [];
});

if (admin_emails.length <= 0) {
logger.warn(`There are no admins yet. No notification email is sent about new user '${newUsername}'.`);
} else {
logger.debug(`Sending notification email about registration of new user '${newUsername}' to ${admin_emails.join(", ")}`);

await sendEmail(
admin_emails,
"New user registered",
`Hi admins,
a new user '${encodeURIComponent(newUsername)}' registered at ${ClientSettings.BASE_URL} .
Visit ${ClientSettings.BASE_URL}/administration in order to give them some permissions.
Kind regards,
Your fuBlog`,
);
}
}

function sendEmail(to: string[], subject: string, text: string) {
if (!(EmailSettings.SMTP_HOST ?? EmailSettings.SMTP_PORT)) {
throw new Error("No SMTP email server set! Cannot send email.");
}

createTransport(EmailSettings.SMTP_OPTIONS)
.sendMail({
from: "[email protected]",
to,
subject,
text,
})
.catch(() => {
logger.error("Failed to send email notification!");
});
}

0 comments on commit e3aab9b

Please sign in to comment.