verfication email & new auth domain
This commit is contained in:
parent
27242819e2
commit
4c19356188
|
|
@ -18,7 +18,17 @@ export class MailController {
|
|||
return await this.mailService.sendRequest(mailInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Post('verify-email')
|
||||
async sendVerificationEmail(@Body() data: {
|
||||
email: string,
|
||||
redirectConfig: {
|
||||
protocol: string,
|
||||
hostname: string,
|
||||
port?: number
|
||||
}
|
||||
}): Promise<void | ErrorResponse> {
|
||||
return await this.mailService.sendVerificationEmail(data.email, data.redirectConfig);
|
||||
}
|
||||
@UseGuards(OptionalAuthGuard)
|
||||
@Post('subscriptionConfirmation')
|
||||
async sendSubscriptionConfirmation(@Body() user: User): Promise<void | ErrorResponse> {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ import { UserModule } from '../user/user.module';
|
|||
import { UserService } from '../user/user.service';
|
||||
import { MailController } from './mail.controller';
|
||||
import { MailService } from './mail.service';
|
||||
// const __filename = fileURLToPath(import.meta.url);
|
||||
// const __dirname = path.dirname(__filename);
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
|
@ -20,32 +18,6 @@ import { MailService } from './mail.service';
|
|||
UserModule,
|
||||
GeoModule,
|
||||
FirebaseAdminModule,
|
||||
// ConfigModule.forFeature(mailConfig),
|
||||
// MailerModule.forRoot({
|
||||
// transport: {
|
||||
// host: 'email-smtp.us-east-2.amazonaws.com',
|
||||
// secure: false,
|
||||
// port: 587,
|
||||
// auth: {
|
||||
// user: user, //'AKIAU6GDWVAQ2QNFLNWN',
|
||||
// pass: password, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
|
||||
// },
|
||||
// },
|
||||
// defaults: {
|
||||
// from: '"No Reply" <noreply@example.com>',
|
||||
// },
|
||||
// template: {
|
||||
// dir: join(__dirname, 'templates'),
|
||||
// adapter: new HandlebarsAdapter({
|
||||
// eq: function (a, b) {
|
||||
// return a === b;
|
||||
// },
|
||||
// }),
|
||||
// options: {
|
||||
// strict: true,
|
||||
// },
|
||||
// },
|
||||
// }),
|
||||
MailerModule.forRootAsync({
|
||||
useFactory: () => ({
|
||||
transport: {
|
||||
|
|
@ -53,8 +25,8 @@ import { MailService } from './mail.service';
|
|||
secure: false,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.AMAZON_USER, //'AKIAU6GDWVAQ2QNFLNWN',
|
||||
pass: process.env.AMAZON_PASSWORD, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
|
||||
user: process.env.AMAZON_USER,
|
||||
pass: process.env.AMAZON_PASSWORD,
|
||||
},
|
||||
},
|
||||
defaults: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { MailerService } from '@nestjs-modules/mailer';
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
import { getAuth } from 'firebase-admin/auth';
|
||||
import { join } from 'path';
|
||||
import { ZodError } from 'zod';
|
||||
import { SenderSchema, ShareByEMail, ShareByEMailSchema, User } from '../models/db.model';
|
||||
|
|
@ -52,6 +53,65 @@ export class MailService {
|
|||
},
|
||||
});
|
||||
}
|
||||
async sendVerificationEmail(
|
||||
email: string,
|
||||
redirectConfig: { protocol: string, hostname: string, port?: number }
|
||||
): Promise<void | ErrorResponse> {
|
||||
try {
|
||||
// Firebase Auth-Instanz holen
|
||||
const auth = getAuth();
|
||||
|
||||
// Baue den Redirect-URL aus den übergebenen Parametern
|
||||
let continueUrl = `${redirectConfig.protocol}://${redirectConfig.hostname}`;
|
||||
if (redirectConfig.port) {
|
||||
continueUrl += `:${redirectConfig.port}`;
|
||||
}
|
||||
continueUrl += '/auth/verify-email-success'; // Beispiel für einen Weiterleitungspfad
|
||||
|
||||
// Custom Verification Link generieren
|
||||
const firebaseActionLink = await auth.generateEmailVerificationLink(email, {
|
||||
url: continueUrl,
|
||||
handleCodeInApp: false,
|
||||
});
|
||||
|
||||
// Extrahiere den oobCode aus dem Firebase Link
|
||||
const actionLinkUrl = new URL(firebaseActionLink);
|
||||
const oobCode = actionLinkUrl.searchParams.get('oobCode');
|
||||
|
||||
if (!oobCode) {
|
||||
throw new BadRequestException('Failed to generate verification code');
|
||||
}
|
||||
|
||||
// Erstelle die benutzerdefinierte URL mit dem oobCode
|
||||
let customActionLink = `${redirectConfig.protocol}://${redirectConfig.hostname}`;
|
||||
if (redirectConfig.port) {
|
||||
customActionLink += `:${redirectConfig.port}`;
|
||||
}
|
||||
|
||||
// Ersetze die Platzhalter mit den tatsächlichen Werten
|
||||
customActionLink += `/email-authorized?email=${encodeURIComponent(email)}&mode=verifyEmail&oobCode=${oobCode}`;
|
||||
|
||||
// Zufallszahl für die E-Mail generieren
|
||||
const randomNumber = Math.floor(Math.random() * 10000);
|
||||
|
||||
// E-Mail senden
|
||||
await this.mailerService.sendMail({
|
||||
to: email,
|
||||
from: '"Bizmatch Team" <info@bizmatch.net>',
|
||||
subject: 'Verify your email address',
|
||||
template: join(__dirname, '../..', 'mail/templates/email-verification.hbs'),
|
||||
context: {
|
||||
actionLink: customActionLink,
|
||||
randomNumber: randomNumber
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error('Error sending verification email:', error);
|
||||
throw new BadRequestException('Failed to send verification email');
|
||||
}
|
||||
}
|
||||
async sendRequest(mailInfo: MailInfo): Promise<void | ErrorResponse> {
|
||||
try {
|
||||
SenderSchema.parse(mailInfo.sender);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,249 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
|
||||
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
|
||||
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
|
||||
<title>Email address verification</title> <!-- The title tag shows in email notifications, like Android 4.4. -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
|
||||
|
||||
<!-- CSS Reset : BEGIN -->
|
||||
<style>
|
||||
/* What it does: Remove spaces around the email design added by some email clients. */
|
||||
/* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
|
||||
html,
|
||||
body {
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
background: #f1f1f1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* What it does: Stops email clients resizing small text. */
|
||||
* {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* What it does: Centers email on Android 4.4 */
|
||||
div[style*="margin: 16px 0"] {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* What it does: Stops Outlook from adding extra spacing to tables. */
|
||||
table,
|
||||
td {
|
||||
mso-table-lspace: 0pt !important;
|
||||
mso-table-rspace: 0pt !important;
|
||||
}
|
||||
|
||||
/* What it does: Fixes webkit padding issue. */
|
||||
table {
|
||||
border-spacing: 0 !important;
|
||||
border-collapse: collapse !important;
|
||||
table-layout: fixed !important;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
/* What it does: Uses a better rendering method when resizing images in IE. */
|
||||
img {
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* What it does: A work-around for email clients meddling in triggered links. */
|
||||
*[x-apple-data-detectors],
|
||||
/* iOS */
|
||||
.unstyle-auto-detected-links *,
|
||||
.aBn {
|
||||
border-bottom: 0 !important;
|
||||
cursor: default !important;
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from displaying a download button on large, non-linked images. */
|
||||
.a6S {
|
||||
display: none !important;
|
||||
opacity: 0.01 !important;
|
||||
}
|
||||
|
||||
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
|
||||
.im {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* If the above doesn't work, add a .g-img class to any image in question. */
|
||||
img.g-img+div {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
|
||||
/* Create one of these media queries for each additional viewport size you'd like to fix */
|
||||
|
||||
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
|
||||
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
|
||||
u~div .email-container {
|
||||
min-width: 320px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* iPhone 6, 6S, 7, 8, and X */
|
||||
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
|
||||
u~div .email-container {
|
||||
min-width: 375px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* iPhone 6+, 7+, and 8+ */
|
||||
@media only screen and (min-device-width: 414px) {
|
||||
u~div .email-container {
|
||||
min-width: 414px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- CSS Reset : END -->
|
||||
|
||||
<!-- Progressive Enhancements : BEGIN -->
|
||||
<style>
|
||||
.primary {
|
||||
background: #30e3ca;
|
||||
}
|
||||
|
||||
.bg_white {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.bg_light {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.bg_black {
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.bg_dark {
|
||||
background: rgba(0, 0, 0, .8);
|
||||
}
|
||||
|
||||
.email-section {
|
||||
padding: 2.5em;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
line-height: 1.8;
|
||||
color: rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
/*HERO*/
|
||||
.hero {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.hero .text {
|
||||
color: rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.hero .text h2 {
|
||||
color: #000;
|
||||
font-size: 40px;
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.hero .text h3 {
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.hero .text h2 span {
|
||||
font-weight: 600;
|
||||
color: #30e3ca;
|
||||
}
|
||||
|
||||
.email-body {
|
||||
display: block;
|
||||
color: black;
|
||||
line-height: 32px;
|
||||
font-weight: 300;
|
||||
font-family: -apple-system, system-ui, BlinkMacSystemFont, sans-serif;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
@media (max-width:400px) {
|
||||
.hero img {
|
||||
width: 200px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body width="100%"
|
||||
style="margin: 0; padding: 0 !important; mso-line-height-rule: exactly; background-color: #f1f1f1; display: flex; align-items: center; justify-content: center;">
|
||||
<div style="width: 100%; background-color: #f1f1f1;">
|
||||
<div
|
||||
style="display: none; font-size: 1px;max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
|
||||
Hello, click on the button below to verify your email address
|
||||
</div>
|
||||
<div style="max-width: 600px; margin: 0 auto;" class="email-container">
|
||||
<!-- BEGIN BODY -->
|
||||
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
|
||||
style="margin: auto;">
|
||||
<tr>
|
||||
<td valign="middle" class="hero bg_white" style="padding: 3em 0 2em 0;">
|
||||
<img src="https://github.com/ColorlibHQ/email-templates/blob/master/10/images/email.png?raw=true"
|
||||
alt="" class="g-img" style="width: 200px; height: auto; margin: auto; display: block;">
|
||||
</td>
|
||||
</tr>
|
||||
<!-- end tr -->
|
||||
<tr>
|
||||
<td valign="middle" class="hero bg_white" style="padding: 2em 0 4em 0;">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="text" style="padding: 0 2.5em; text-align: center;">
|
||||
<h2 style="margin-bottom: 20px; font-size: 32px;">Verify your email address</h2>
|
||||
<p class="email-body">
|
||||
Thanks for signup with us. Click on the button below to verify your email
|
||||
address.
|
||||
</p>
|
||||
<a href="{{actionLink}}" target="_blank"
|
||||
style="padding:15px 40px; background-color: #5D91E8; color: white;">Verify
|
||||
your email</a>
|
||||
<p class="email-body">
|
||||
If this email wasn't intended for you feel free to delete it.<br />
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- end tr -->
|
||||
<span style="color: #f1f1f1; display: none;">{{randomNumber}}</span>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -2,9 +2,10 @@
|
|||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { FirebaseApp } from '@angular/fire/app';
|
||||
import { GoogleAuthProvider, UserCredential, createUserWithEmailAndPassword, getAuth, sendEmailVerification, signInWithEmailAndPassword, signInWithPopup } from 'firebase/auth';
|
||||
import { GoogleAuthProvider, UserCredential, createUserWithEmailAndPassword, getAuth, signInWithEmailAndPassword, signInWithPopup } from 'firebase/auth';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { MailService } from './mail.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
|
@ -13,6 +14,7 @@ export class AuthService {
|
|||
private app = inject(FirebaseApp);
|
||||
private auth = getAuth(this.app);
|
||||
private http = inject(HttpClient);
|
||||
private mailService = inject(MailService);
|
||||
|
||||
// Registrierung mit Email und Passwort
|
||||
async registerWithEmail(email: string, password: string): Promise<UserCredential> {
|
||||
|
|
@ -41,7 +43,17 @@ async registerWithEmail(email: string, password: string): Promise<UserCredential
|
|||
|
||||
// E-Mail-Verifizierung mit den angepassten ActionCode-Einstellungen senden
|
||||
if (userCredential.user) {
|
||||
await sendEmailVerification(userCredential.user, actionCodeSettings);
|
||||
//await sendEmailVerification(userCredential.user, actionCodeSettings);
|
||||
this.mailService.sendVerificationEmail(userCredential.user.email).subscribe({
|
||||
next: () => {
|
||||
console.log('Verification email sent successfully');
|
||||
// Erfolgsmeldung anzeigen
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error sending verification email', error);
|
||||
// Fehlermeldung anzeigen
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Token, RefreshToken und ggf. photoURL speichern
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { lastValueFrom, Observable } from 'rxjs';
|
||||
import { ShareByEMail } from '../../../../bizmatch-server/src/models/db.model';
|
||||
import { ErrorResponse, MailInfo } from '../../../../bizmatch-server/src/models/main.model';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
|
@ -18,4 +18,32 @@ export class MailService {
|
|||
async mailToFriend(shareByEMail: ShareByEMail): Promise<void | ErrorResponse> {
|
||||
return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/mail/send2Friend`, shareByEMail));
|
||||
}
|
||||
/**
|
||||
* Sendet eine E-Mail-Verifizierung an die angegebene E-Mail-Adresse
|
||||
* @param email Die E-Mail-Adresse des Benutzers
|
||||
* @param redirectConfig Konfiguration für die Weiterleitung nach Verifizierung
|
||||
* @returns Observable mit der API-Antwort
|
||||
*/
|
||||
sendVerificationEmail(
|
||||
email: string,
|
||||
redirectConfig?: {
|
||||
protocol?: string,
|
||||
hostname?: string,
|
||||
port?: number
|
||||
}
|
||||
): Observable<any> {
|
||||
// Extrahiere aktuelle URL-Informationen, wenn nicht explizit angegeben
|
||||
const currentUrl = new URL(window.location.href);
|
||||
|
||||
const config = {
|
||||
protocol: redirectConfig?.protocol || currentUrl.protocol.replace(':', ''),
|
||||
hostname: redirectConfig?.hostname || currentUrl.hostname,
|
||||
port: redirectConfig?.port || (currentUrl.port ? parseInt(currentUrl.port) : undefined)
|
||||
};
|
||||
|
||||
return this.http.post(`${this.apiBaseUrl}/bizmatch/mail/verify-email`, {
|
||||
email,
|
||||
redirectConfig: config
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ export const environment_base = {
|
|||
ipinfo_token: '7029590fb91214',
|
||||
firebaseConfig: {
|
||||
apiKey: 'AIzaSyBqVutQqdgUzwD9tKiKJrJq2Q6rD1hNdzw',
|
||||
authDomain: 'bizmatch-net.firebaseapp.com',
|
||||
//authDomain: 'bizmatch-net.firebaseapp.com',
|
||||
authDomain: 'auth.bizmatch.net',
|
||||
projectId: 'bizmatch-net',
|
||||
storageBucket: 'bizmatch-net.firebasestorage.app',
|
||||
messagingSenderId: '1065122571067',
|
||||
|
|
|
|||
Loading…
Reference in New Issue