Auth korrigiert & mail based on SES

This commit is contained in:
Andreas Knuth 2024-03-12 20:26:58 +01:00
parent be146fdc6a
commit f3868da8f8
7 changed files with 96 additions and 35 deletions

View File

@ -1,14 +1,15 @@
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { MailService } from './mail.service.js';
import { MailInfo } from '../models/server.model.js';
import { KeycloakUser, MailInfo } from 'src/models/main.model.js';
@Controller('mail')
export class MailController {
constructor(private mailService:MailService){
}
@Post(':id')
sendEMail(@Param('id') id:string,@Body() mailInfo: MailInfo): any {
return this.mailService.sendInquiry(id,mailInfo);
@Post()
sendEMail(@Body() mailInfo: MailInfo): Promise< KeycloakUser> {
return this.mailService.sendInquiry(mailInfo);
}
}

View File

@ -1,24 +1,26 @@
import { MailerService } from '@nestjs-modules/mailer';
import { Injectable } from '@nestjs/common';
import { AuthService } from '../auth/auth.service.js';
import { MailInfo } from '../models/server.model.js';
import { User } from 'src/models/main.model.js';
import { KeycloakUser, MailInfo, User } from '../models/main.model.js';
@Injectable()
export class MailService {
constructor(private mailerService: MailerService, private authService:AuthService) {}
async sendInquiry(userId:string,mailInfo: MailInfo) {
const user = await this.authService.getUser(userId) as User;
async sendInquiry(mailInfo: MailInfo):Promise<KeycloakUser> {
const user = await this.authService.getUser(mailInfo.userId) as KeycloakUser;
console.log(JSON.stringify(user));
await this.mailerService.sendMail({
to: user.email,
from: '"Bizmatch Team" <info@bizmatch.net>', // override default from
subject: `Inquiry from ${mailInfo.sender.name}`,
template: './inquiry', // `.hbs` extension is appended automatically
context: { // ✏️ filling curly brackets with content
name: user.firstname,
name: user.firstName,
inquiry:mailInfo.sender.comments
},
});
return user
}
}

View File

@ -1,17 +1,7 @@
import { Entity } from "redis-om";
import { UserBase } from "./main.model.js";
export interface MailInfo {
sender: Sender;
userId: string;
}
export interface Sender {
name: string;
email: string;
phoneNumber: string;
state: string;
comments: string;
}
export interface Geo {
id: number;
name: string;

View File

@ -115,29 +115,29 @@
<div class="font-italic text-sm text-900 mb-5">Please Include your contact info below:</div>
<div class="grid formgrid p-fluid">
<div class="field mb-4 col-12 md:col-6">
<label for="company_name" class="font-medium text-900">Your Name</label>
<input id="company_name" type="text" pInputText>
<label for="name" class="font-medium text-900">Your Name</label>
<input id="name" type="text" pInputText [(ngModel)]="mailinfo.sender.name">
</div>
<div class="field mb-4 col-12 md:col-6">
<label for="invoice_id" class="font-medium text-900">Your Email</label>
<input id="invoice_id" type="text" pInputText>
<label for="email" class="font-medium text-900">Your Email</label>
<input id="email" type="text" pInputText [(ngModel)]="mailinfo.sender.email">
</div>
<div class="field mb-4 col-12 md:col-6">
<label for="customer_name" class="font-medium text-900">Phone Number</label>
<input id="customer_name" type="text" pInputText>
<label for="phoneNumber" class="font-medium text-900">Phone Number</label>
<input id="phoneNumber" type="text" pInputText [(ngModel)]="mailinfo.sender.phoneNumber">
</div>
<div class="field mb-4 col-12 md:col-6">
<label for="customer_email" class="font-medium text-900">Country/State</label>
<input id="customer_email" type="text" pInputText>
<label for="state" class="font-medium text-900">Country/State</label>
<input id="state" type="text" pInputText [(ngModel)]="mailinfo.sender.state">
</div>
<div class="surface-border border-top-1 opacity-50 mb-4 col-12"></div>
<div class="field mb-4 col-12">
<label for="notes" class="font-medium text-900">Questions/Comments</label>
<textarea id="notes" pInputTextarea [autoResize]="true" [rows]="5"></textarea>
<textarea id="notes" pInputTextarea [autoResize]="true" [rows]="5" [(ngModel)]="mailinfo.sender.comments"></textarea>
</div>
<div class="surface-border border-top-1 opacity-50 mb-4 col-12"></div>
</div>
<button pButton pRipple label="Submit" icon="pi pi-file" class="w-auto"></button>
<button pButton pRipple label="Submit" icon="pi pi-file" class="w-auto" (click)="mail()"></button>
</div>
</div>
</div>

View File

@ -17,12 +17,16 @@ import { lastValueFrom } from 'rxjs';
import { ListingsService } from '../../services/listings.service';
import { UserService } from '../../services/user.service';
import onChange from 'on-change';
import { getCriteriaStateObject, getSessionStorageHandler } from '../../utils/utils';
import { ListingCriteria, ListingType, User } from '../../../../../common-models/src/main.model';
import { createGenericObject, getCriteriaStateObject, getSessionStorageHandler } from '../../utils/utils';
import { ListingCriteria, ListingType, MailInfo, User } from '../../../../../common-models/src/main.model';
import { MailService } from '../../services/mail.service';
import { MessageService } from 'primeng/api';
import { SharedModule } from '../../shared/shared/shared.module';
@Component({
selector: 'app-details',
standalone: true,
imports: [CommonModule, StyleClassModule, ButtonModule, CheckboxModule, InputTextModule, DropdownModule, FormsModule, ChipModule,InputTextareaModule,RouterModule],
imports: [SharedModule],
providers:[MessageService],
templateUrl: './details.component.html',
styleUrl: './details.component.scss'
})
@ -33,8 +37,17 @@ export class DetailsComponent {
listing: ListingType;
user:User;
criteria:ListingCriteria
constructor(private activatedRoute: ActivatedRoute,private listingsService:ListingsService,private router:Router,private userService:UserService,public selectOptions: SelectOptionsService){
mailinfo: MailInfo;
constructor(private activatedRoute: ActivatedRoute,
private listingsService:ListingsService,
private router:Router,
private userService:UserService,
public selectOptions: SelectOptionsService,
private mailService:MailService,
private messageService: MessageService){
this.criteria = onChange(getCriteriaStateObject(),getSessionStorageHandler);
this.mailinfo = {sender:{},userId:''}
}
async ngOnInit(){
@ -47,4 +60,9 @@ export class DetailsComponent {
isAdmin(){
return this.userService.hasAdminRole();
}
async mail(){
this.mailinfo.userId=this.listing.userId;
await this.mailService.mail(this.mailinfo);
this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'Your message has been sent to the creator of the listing', life: 3000 });
}
}

View File

@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
import { MailInfo } from '../../../../common-models/src/main.model';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { lastValueFrom } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MailService {
private apiBaseUrl = environment.apiBaseUrl;
constructor(private http: HttpClient) { }
async mail(mailinfo:MailInfo):Promise<void>{
await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/mail`,mailinfo));
}
}

View File

@ -88,7 +88,28 @@ export interface UserBase {
export interface User extends UserBase {
licensedIn?:KeyValue[];
}
export interface KeycloakUser {
id: string
createdTimestamp: number
username: string
enabled: boolean
totp: boolean
emailVerified: boolean
firstName: string
lastName: string
email: string
disableableCredentialTypes: any[]
requiredActions: any[]
notBefore: number
access: Access
}
export interface Access {
manageGroupMembership: boolean
view: boolean
mapRoles: boolean
impersonate: boolean
manage: boolean
}
export interface Subscription {
id: string;
userId:string
@ -144,4 +165,15 @@ export interface PageEvent {
export interface AutoCompleteCompleteEvent {
originalEvent: Event;
query: string;
}
export interface MailInfo {
sender: Sender;
userId: string;
}
export interface Sender {
name?: string;
email?: string;
phoneNumber?: string;
state?: string;
comments?: string;
}