diff --git a/.github/workflows/npmjs_publish.yaml b/.github/workflows/npmjs_publish.yaml new file mode 100644 index 0000000..4097a88 --- /dev/null +++ b/.github/workflows/npmjs_publish.yaml @@ -0,0 +1,37 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages + +name: Publish @sctg/web-smtp-relay-client to NPMJS + +on: + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - run: cd web-smtp-relay-client + - run: npm ci + - run: npm run build + - run: npm test + + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org/ + - run: cd web-smtp-relay-client + - run: npm ci + - run: npm run build + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.NPMJS_TOKEN}} \ No newline at end of file diff --git a/README.md b/README.md index a5d3b26..378ddf6 100644 --- a/README.md +++ b/README.md @@ -125,31 +125,31 @@ This project includes a Helm chart for easy deployment to Kubernetes clusters. T 1. If you don't want to install the chart you can use our public Helm repository: - ```bash +```bash - helm repo add highcanfly - helm repo update highcanfly +helm repo add highcanfly +helm repo update highcanfly - ``` +``` - Then install the chart: +Then install the chart: - ```bash - helm upgrade --install --create-namespace --namespace web-smtp-relay web-smtp-relay highcanfly/web-smtp-relay --values values.yaml - ``` +```bash +helm upgrade --install --create-namespace --namespace web-smtp-relay web-smtp-relay highcanfly/web-smtp-relay --values values.yaml +``` 2. Clone the repository or download the Helm chart files. 3. Navigate to the chart directory: - ```bash - cd web-smtp-relay - ``` +```bash +cd web-smtp-relay +``` 4. Install the chart with the release name `my-web-smtp-relay`: - ```bash - helm install my-web-smtp-relay . +```bash +helm install my-web-smtp-relay . ``` ### Customizing the Chart diff --git a/web-smtp-relay-client/.gitignore b/web-smtp-relay-client/.gitignore new file mode 100644 index 0000000..3e7f8dd --- /dev/null +++ b/web-smtp-relay-client/.gitignore @@ -0,0 +1,115 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test +.env.production + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# VS Code directories +.vscode/ +.history/ + +# SvelteKit build / generate output +.svelte-kit + +# Temporary folders +tmp/ +temp/ \ No newline at end of file diff --git a/web-smtp-relay-client/README.md b/web-smtp-relay-client/README.md new file mode 100644 index 0000000..c577f7e --- /dev/null +++ b/web-smtp-relay-client/README.md @@ -0,0 +1,39 @@ +# @sctg/web-smtp-relay-client + +A simple client for the web-smtp-relay server. + +## Installation + +```bash +npm install @sctg/web-smtp-relay-client +``` + +## Usage + +```typescript +import { WebSMTPRelayClient, WebSMTPRelayConfig, EmailMessage } from '@sctg/web-smtp-relay-client'; + +const config: WebSMTPRelayConfig = { + scheme: 'https', + host: 'localhost', + port: 8080, + username: 'admin', + password: 'admin123' +}; + +const client = new WebSMTPRelayClient(config); + +const message: EmailMessage = { + subject: 'Test Subject', + body: 'This is a test email', + destinations: ['recipient@example.com'] +}; + +client.sendEmail(message) + .then(() => console.log('Email sent successfully')) + .catch((error) => console.error('Error sending email:', error)); +``` + +## License + +This project is licensed under the GNU Affero General Public License v3.0 (AGPLv3). diff --git a/web-smtp-relay-client/package-lock.json b/web-smtp-relay-client/package-lock.json new file mode 100644 index 0000000..ebdbabe --- /dev/null +++ b/web-smtp-relay-client/package-lock.json @@ -0,0 +1,111 @@ +{ + "name": "@sctg/web-smtp-relay-client", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@sctg/web-smtp-relay-client", + "version": "1.0.0", + "license": "AGPL-3.0", + "devDependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "@types/node": "^20", + "typescript": "^5.5.4" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz", + "integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz", + "integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@types/node": { + "version": "20.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", + "integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/web-smtp-relay-client/package.json b/web-smtp-relay-client/package.json new file mode 100644 index 0000000..da8fe5d --- /dev/null +++ b/web-smtp-relay-client/package.json @@ -0,0 +1,24 @@ +{ + "name": "@sctg/web-smtp-relay-client", + "version": "1.0.0", + "description": "A simple client for the web-smtp-relay server", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "private": false, + "scripts": { + "build": "tsc", + "prepublishOnly": "npm run build" + }, + "keywords": ["smtp", "relay", "client"], + "author": "Ronan LE MEILLAT", + "license": "AGPL-3.0", + "devDependencies": { + "typescript": "^5.5.4", + "@types/node": "^20", + "@babel/parser": "^7.25.4", + "@babel/types":"^7.25.4" + }, + "files": [ + "dist/**/*" + ] + } \ No newline at end of file diff --git a/web-smtp-relay-client/src/index.ts b/web-smtp-relay-client/src/index.ts new file mode 100644 index 0000000..55c6605 --- /dev/null +++ b/web-smtp-relay-client/src/index.ts @@ -0,0 +1,39 @@ +export interface WebSMTPRelayConfig { + scheme: string; + host: string; + port: number; + username: string; + password: string; +} + +export interface EmailMessage { + subject: string; + body: string; + destinations: string[]; +} + +export class WebSMTPRelayClient { + private config: WebSMTPRelayConfig; + + constructor(config: WebSMTPRelayConfig) { + this.config = config; + } + + async sendEmail(message: EmailMessage): Promise { + const url = `${this.config.scheme}://${this.config.host}:${this.config.port}/send`; + const auth = Buffer.from(`${this.config.username}:${this.config.password}`).toString('base64'); + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Basic ${auth}`, + }, + body: JSON.stringify(message), + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + } +} \ No newline at end of file diff --git a/web-smtp-relay-client/tsconfig.json b/web-smtp-relay-client/tsconfig.json new file mode 100644 index 0000000..559ce38 --- /dev/null +++ b/web-smtp-relay-client/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "importHelpers": true, + "isolatedModules": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "declaration": true, + "skipLibCheck": true, + "outDir": "./dist", + "strict": true, + }, + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "**/__tests__/*" + ] +} \ No newline at end of file