Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ekulno committed Apr 5, 2024
0 parents commit c342fa1
Show file tree
Hide file tree
Showing 14 changed files with 929 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

on:
push:
branches:
- "*"

jobs:
docker_build_and_publish:
name: Build and push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2

- name: Push to Docker Hub
uses: docker/build-push-action@v1 # Info: https://github.com/docker/build-push-action/tree/releases/v1#tags
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: ${{ secrets.DOCKERHUB_REPOSITORY }}
tag_with_ref: true # Info: https://github.com/docker/build-push-action/tree/releases/v1#tag_with_ref
tag_with_sha: true # Info: https://github.com/docker/build-push-action/tree/releases/v1#tag_with_sha
tags: ${{ env.GITHUB_REF }}
# helm_build_and_publish:
# name: Build and push helm chart
# runs-on: ubuntu-latest
# steps: [ ]
# update_gitops:
# name: Update Gitops repo to use latest version
# runs-on: ubuntu-latest
# steps: [ ]
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
lib
tsconfig.tsbuildinfo
.envrc
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:21-alpine

WORKDIR /usr/src/app

COPY package.json /usr/src/app
COPY yarn.lock /usr/src/app

RUN yarn

COPY src /usr/src/app/src
COPY tsconfig.json /usr/src/app

RUN yarn build

COPY assets /usr/src/app/assets

CMD node lib/index.js
39 changes: 39 additions & 0 deletions assets/contact.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>

<head>
<title>Eirik Kultorp's homepage</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<script type="application/ld+json" data-rh="true">
{
"@context": "https://schema.org/",
"@type": "WebPage",
"url": "https://ekul.no/contact",
"mainEntity": {
"@id": "https://ekul.no/eirik-kultorp",
"@type": "Person",
"image": "https://ekul.no/portrait.png",
"name": "Eirik Kultorp",
"url": "https://ekul.no"
}
}
</script>
</head>
<body>
<main>
<h1>Contact me</h1>
<p>
Leave me a message
</p>

<form action="contact" method=post>
<input type="email" name="email" placeholder="Your email address" />
<textarea name="message" placeholder="Message"></textarea>
<input type="submit" value="Send" />
</form>

</main>
</body>

</html>
42 changes: 42 additions & 0 deletions assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>

<head>
<title>Eirik Kultorp's homepage</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<script type="application/ld+json" data-rh="true">
{
"@context": "https://schema.org/",
"@type": "WebPage",
"url": "https://ekul.no",
"mainEntity": {
"@id": "https://ekul.no/eirik-kultorp",
"@type": "Person",
"image": "https://ekul.no/portrait.png",
"name": "Eirik Kultorp",
"url": "https://ekul.no"
}
}
</script>
</head>

<body>
<main>
<h1>Eirik Kultorp</h1>
<p>
Software engineer interested in high-performance computing, devops and infra, and knowledge representation.
Enjoys sci-fi and racket sports.
Based in Oslo.
</p>
<p id="links">
<a href="https://github.com/ekulno">Github</a>
<a href="https://www.linkedin.com/in/eirik-kultorp-aa0225256/">LinkedIn</a>
<a href="./contact">Contact</a>
</p>

<img src="portrait.png" id="portrait" />
</main>
</body>

</html>
Binary file added assets/portrait.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions assets/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.social-button {
height: 2em;
width: 2em;
}


body {
height: 100vh;
margin: 0;
}

main {
display: flex;
flex-direction: column;
align-items: center;
font-family: 'Courier';
height: 100%;
font-size: 1em;
}

#portrait {
width: 150px;
border-radius: 100%;
}

main>* {
max-width: 19em;
text-align: center;
}

input,
textarea {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
box-sizing: border-box;
}

textarea {
height: 10em;
}
33 changes: 33 additions & 0 deletions assets/thanks.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>

<head>
<title>Eirik Kultorp's homepage</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<script type="application/ld+json" data-rh="true">
{
"@context": "https://schema.org/",
"@type": "WebPage",
"url": "https://ekul.no/contact",
"mainEntity": {
"@id": "https://ekul.no/eirik-kultorp",
"@type": "Person",
"image": "https://ekul.no/portrait.png",
"name": "Eirik Kultorp",
"url": "https://ekul.no"
}
}
</script>
</head>

<body>
<main>
<h1>Message sent</h1>
<p>
Thanks for your message!
</p>
</main>
</body>

</html>
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '2'
services:
homepage:
build: .
ports:
- "3000:3000"
environment:
PORT: 3000
TO_EMAIL: $TO_EMAIL
SMTP_HOST: $SMTP_HOST
SMTP_SECURE: $SMTP_SECURE
SMTP_PORT: $SMTP_PORT
SMTP_SERVICE: $SMTP_SERVICE
SMTP_AUTH_USER: $SMTP_AUTH_USER
SMTP_AUTH_PASS: $SMTP_AUTH_PASS
24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"scripts": {
"build": "tsc",
"start": "nodemon lib/index.js"
},
"dependencies": {
"@types/express": "^4.17.21",
"@types/nodemailer": "^6.4.14",
"body-parser": "^1.20.2",
"email-validator": "^2.0.4",
"express": "^4.18.2",
"express-async-errors": "^3.1.1",
"nodemailer": "^6.9.10",
"typescript": "^5.3.3"
},
"type": "module",
"name": "mailer",
"version": "0.0.1",
"description": "writes an email to a preconfigured address upon receipt of a post request",
"main": "lib/index.js",
"repository": "https://github.com/ekulno/contact-form-mailer",
"author": "ekulno",
"license": "MIT"
}
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# homepage

Source of my homepage [ekul.no](https://ekul.no).
83 changes: 83 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import 'express-async-errors';
import express, {NextFunction, Request, Response} from "express";
import bodyParser from "body-parser";
import nodemailer from 'nodemailer';
import { validate as validateEmail } from 'email-validator';

const app = express();

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

const port = process.env['PORT'] || 3000;

const toMail = process.env['TO_EMAIL'];

const smtp = {
service: process.env['SMTP_SERVICE']!,
host: process.env['SMTP_HOST']!,
port: parseInt(process.env['SMTP_PORT']!),
secure: !!(process.env['SMTP_SECURE'] && process.env['SMTP_SECURE'] != 'false'),
auth: {
user: process.env['SMTP_AUTH_USER']!,
pass: process.env['SMTP_AUTH_PASS']!,
}
}

const transporter = nodemailer.createTransport(smtp);

interface ContactRequest {
email: string;
message: string;
name?: string;
subject?: string;
};

app.get('/', async (req, res)=>{
res.sendFile(process.cwd()+'/assets/index.html')
});
app.get('/style.css', async (req, res)=>{
res.sendFile(process.cwd()+'/assets/style.css')
});
app.get('/portrait.png', async (req, res)=>{
res.sendFile(process.cwd()+'/assets/portrait.png')
});
app.get('/contact', async (req, res)=>{
res.sendFile(process.cwd()+'/assets/contact.html')
});

app.post("/contact", async (req, res) => {
const { email, message, name, subject } = req.body as ContactRequest;
if (!validateEmail(email)) {
res.status(400).send("Invalid email");
return;
}
if (!message.trim()) {
res.status(400).send("No message");
return;
}
const info = await transporter.sendMail({
from: `<${smtp.auth.user}>`,
replyTo: `${name?`"${name}"`:''} <${email}>`,
to: toMail,
subject: subject || "Contact form message",
text: message
});

if (info.rejected.length) {
res.status(500).send("Failed to send message");
return;
}
res.sendFile(process.cwd()+'/assets/thanks.html')
});

app.use(async (err:Error, req:Request, res:Response, next:NextFunction) => {
console.error(err.stack)
res.status(500).send('Internal server error');
return;
});


app.listen(port, () => {
console.log(`[server]: Server is running at http://localhost:${port}`);
});
17 changes: 17 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution":"node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,

"outDir": "./lib",
"rootDir": "./src"
},
"preserveSymlinks": false,
"compileOnSave": true,
"include": ["./src/**/*"],
}
Loading

0 comments on commit c342fa1

Please sign in to comment.