diff --git a/app/lib/actions.ts b/app/lib/actions.ts index e4b254f..58b8342 100644 --- a/app/lib/actions.ts +++ b/app/lib/actions.ts @@ -2,9 +2,22 @@ import { z } from 'zod'; import { getVCFor } from './vc-templates/getVC'; +import nodemailer from 'nodemailer' +const host = process.env.SMTP_HOST +const user = process.env.SMTP_USER +const pass = process.env.SMTP_PASS +const port = process.env.SMTP_PORT const exchangeHost = process.env.EXCHANGE_HOST +const smtpOptions : any = { + host, + auth: { user, pass }, + ...(port && {port}) +} + +const transporter = nodemailer.createTransport(smtpOptions) + const FormSchema = z.object({ recipientName: z.string().trim() .min(1, { message: "You must enter a name." }), @@ -52,12 +65,10 @@ async function issueToLCW(vc:object):Promise { const result = await postData(`${exchangeHost}/exchange/setup`, dataToPost) const deepLink = result[0]; const splitOnSlash = deepLink.directDeepLink.split('/') - console.log(splitOnSlash) const transactionId = splitOnSlash.pop() const exchangeId = splitOnSlash.pop() deepLink.collectionPageURL = `${exchangeHost}/tryit/collect?exchangeId=${exchangeId}&transactionId=${transactionId}` - console.log("the result:") - console.log(result) + sendMail(`Your credential: ${deepLink.collectionPageURL}`, 'jc.chartrand@gmail.com') return {deepLink} // the links could be emailed out. but show them here first. } @@ -96,8 +107,7 @@ export async function issueCredential(prevState: State, formData: FormData) { const { delivery, revocable } = validatedFields.data; const vc = getVCFor(validatedFields.data) - console.log("the vc:") - console.log(vc) + // Call the signing service try { @@ -132,4 +142,20 @@ async function postData(url = "", data = {}) { return response.json(); } +async function sendMail(message:string, recipient:string) { + try { + const messageParams = { + from: process.env.EMAIL_FROM, + to: recipient, + subject: "You've got a credential!", + text: message + } + await transporter.sendMail(messageParams) + } catch (error) { + console.log('the email send error: ') + console.log(error) + } +} + + diff --git a/package.json b/package.json index cf27485..6a0d51d 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "handlebars": "^4.7.8", "next": "latest", "next-auth": "5.0.0-beta.19", + "nodemailer": "^6.10.0", "postcss": "8.4.49", "react": "19.0.0", "react-copy-to-clipboard": "^5.1.0", @@ -28,6 +29,7 @@ "devDependencies": { "@types/bcrypt": "^5.0.2", "@types/node": "22.10.1", + "@types/nodemailer": "^6.4.17", "@types/react": "19.0.0", "@types/react-copy-to-clipboard": "^5.0.7", "@types/react-dom": "19.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1e7efb..8fe5348 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,10 @@ importers: version: 15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) next-auth: specifier: 5.0.0-beta.19 - version: 5.0.0-beta.19(next@15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) + version: 5.0.0-beta.19(next@15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(nodemailer@6.10.0)(react@19.0.0) + nodemailer: + specifier: ^6.10.0 + version: 6.10.0 postcss: specifier: 8.4.49 version: 8.4.49 @@ -69,6 +72,9 @@ importers: '@types/node': specifier: 22.10.1 version: 22.10.1 + '@types/nodemailer': + specifier: ^6.4.17 + version: 6.4.17 '@types/react': specifier: 19.0.0 version: 19.0.0 @@ -331,6 +337,9 @@ packages: '@types/node@22.10.1': resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} + '@types/nodemailer@6.4.17': + resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} + '@types/pg@8.11.6': resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} @@ -787,6 +796,10 @@ packages: node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + nodemailer@6.10.0: + resolution: {integrity: sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==} + engines: {node: '>=6.0.0'} + nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} @@ -1214,7 +1227,7 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@auth/core@0.32.0': + '@auth/core@0.32.0(nodemailer@6.10.0)': dependencies: '@panva/hkdf': 1.2.1 '@types/cookie': 0.6.0 @@ -1223,6 +1236,8 @@ snapshots: oauth4webapi: 2.17.0 preact: 10.11.3 preact-render-to-string: 5.2.3(preact@10.11.3) + optionalDependencies: + nodemailer: 6.10.0 '@emnapi/runtime@1.3.1': dependencies: @@ -1417,6 +1432,10 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/nodemailer@6.4.17': + dependencies: + '@types/node': 22.10.1 + '@types/pg@8.11.6': dependencies: '@types/node': 22.10.1 @@ -1809,11 +1828,13 @@ snapshots: neo-async@2.6.2: {} - next-auth@5.0.0-beta.19(next@15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0): + next-auth@5.0.0-beta.19(next@15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(nodemailer@6.10.0)(react@19.0.0): dependencies: - '@auth/core': 0.32.0 + '@auth/core': 0.32.0(nodemailer@6.10.0) next: 15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react: 19.0.0 + optionalDependencies: + nodemailer: 6.10.0 next@15.0.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: @@ -1850,6 +1871,8 @@ snapshots: node-releases@2.0.18: {} + nodemailer@6.10.0: {} + nopt@5.0.0: dependencies: abbrev: 1.1.1