Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft tests, implement email verification #1

Merged
merged 3 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ BEHIND_PROXY=
MAILER_IDENTITY_EMAIL=bot@example
MAILER_IDENTITY_PASSWORD=password
MAILER_IDENTITY_PROVIDER=http://localhost:3456
MAILER_IDENTITY_WEBID=http://localhost:3456/bot/profile/card#me

# link to group of users who are allowed to use the service
ALLOWED_GROUPS=

# SMTP Transport for sending emails
# string or undefined
Expand All @@ -39,3 +43,10 @@ DB_USERNAME=
DB_PASSWORD=
DB_HOST=
DB_PORT=

# JWT
# path to JWT (private) key
# you can use the command `openssl ecparam -name prime256v1 -genkey -noout -out ecdsa-p256-private.pem` to generate one
JWT_KEY=./ecdsa-p256-private.pem
# jwt algorithm
JWT_ALG=ES256
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ jobs:
- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Generate private key
run: openssl ecparam -name prime256v1 -genkey -noout -out ecdsa-p256-private.pem

- name: Run tests
run: yarn test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ output
node_modules

database.sqlite

*.pem
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"@types/bcryptjs": "^2.4.2",
"@types/chai": "^4.3.5",
"@types/co-body": "^6.1.0",
"@types/fs-extra": "^11.0.4",
"@types/jsonwebtoken": "^9.0.5",
"@types/koa": "^2.13.7",
"@types/koa-static": "^4.0.3",
"@types/koa__cors": "^4.0.1",
Expand All @@ -37,6 +39,7 @@
"eslint-plugin-prettier": "^5.0.0",
"maildev": "^2.1.0",
"mocha": "^10.2.0",
"msw": "^2.0.14",
"prettier": "^3.0.0",
"rdf-namespaces": "^1.11.0",
"sinon": "^15.2.0",
Expand All @@ -57,6 +60,8 @@
"cross-fetch": "^4.0.0",
"css-authn": "^0.0.14",
"dotenv": "^16.0.0",
"fs-extra": "^11.2.0",
"jsonwebtoken": "^9.0.2",
"koa": "^2.14.2",
"koa-helmet": "^7.0.2",
"koa-static": "^5.0.0",
Expand Down
96 changes: 62 additions & 34 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import Router from '@koa/router'
import Koa from 'koa'
import helmet from 'koa-helmet'
import serve from 'koa-static'
import { isBehindProxy } from './config'
import { allowedGroups, isBehindProxy } from './config'
import {
checkVerificationLink,
finishIntegration,
initializeIntegration,
} from './controllers/integration'
import { getStatus } from './controllers/status'
import { webhookReceiver } from './controllers/webhookReceiver'
import { authorizeGroups } from './middlewares/authorizeGroup'
import { solidAuth } from './middlewares/solidAuth'
import { validateBody } from './middlewares/validate'

Expand All @@ -20,42 +21,69 @@ app.proxy = isBehindProxy
const router = new Router()

router
// .post(
// '/inbox',
// solidAuth,
// /*
// #swagger.requestBody = {
// required: true,
// content: {
// 'application/json': {
// schema: {
// type: 'object',
// properties: {
// '@context': { const: 'https://www.w3.org/ns/activitystreams' },
// '@id': { type: 'string' },
// '@type': { const: 'Add' },
// actor: { type: 'string', format: 'uri' },
// object: { type: 'string', format: 'uri' },
// target: { type: 'string', format: 'email' },
// },
// required: ['@context', '@type', 'actor', 'object', 'target'],
// additionalProperties: false,
// },
// },
// },
// }
// */
// validateBody({
// type: 'object',
// properties: {
// '@context': { const: 'https://www.w3.org/ns/activitystreams' },
// '@id': { type: 'string' },
// '@type': { const: 'Add' },
// actor: { type: 'string', format: 'uri' },
// object: { type: 'string', format: 'uri' },
// target: { type: 'string', format: 'email' },
// },
// required: ['@context', '@type', 'actor', 'object', 'target'],
// additionalProperties: false,
// }),
// initializeIntegration,
// )
.post(
'/inbox',
'/init',
solidAuth,
/*
#swagger.requestBody = {
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
'@context': { const: 'https://www.w3.org/ns/activitystreams' },
'@id': { type: 'string' },
'@type': { const: 'Add' },
actor: { type: 'string', format: 'uri' },
object: { type: 'string', format: 'uri' },
target: { type: 'string', format: 'email' },
},
required: ['@context', '@type', 'actor', 'object', 'target'],
additionalProperties: false,
},
},
},
}
*/
authorizeGroups(allowedGroups),
// #swagger.requestBody = {
// required: true,
// content: {
// 'application/json': {
// schema: {
// type: 'object',
// properties: {
// email: { type: 'string', format: 'email' },
// },
// required: ['email'],
// additionalProperties: false,
// },
// },
// },
// }
validateBody({
type: 'object',
properties: {
'@context': { const: 'https://www.w3.org/ns/activitystreams' },
'@id': { type: 'string' },
'@type': { const: 'Add' },
actor: { type: 'string', format: 'uri' },
object: { type: 'string', format: 'uri' },
target: { type: 'string', format: 'email' },
},
required: ['@context', '@type', 'actor', 'object', 'target'],
properties: { email: { type: 'string', format: 'email' } },
required: ['email'],
additionalProperties: false,
}),
initializeIntegration,
Expand All @@ -71,7 +99,7 @@ app
bodyParser({
enableTypes: ['text', 'json'],
extendTypes: {
json: ['application/ld+json'],
json: ['application/ld+json', 'application/json'],
text: ['text/turtle'],
},
}),
Expand Down
21 changes: 19 additions & 2 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export const mailerCredentials = {
email: process.env.MAILER_IDENTITY_EMAIL ?? 'bot@example',
password: process.env.MAILER_IDENTITY_PASSWORD ?? 'password',
provider: process.env.MAILER_IDENTITY_PROVIDER ?? 'http://localhost:3456',
webId:
process.env.MAILER_IDENTITY_WEBID ??
'http://localhost:3456/bot/profile/card#me',
}

const stringToBoolean = (value: string | undefined): boolean => {
Expand All @@ -39,8 +42,8 @@ export const emailSender = process.env.EMAIL_SENDER

export const port: number = +(process.env.PORT ?? 3005)

// email verification expiration in milliseconds (1 hour)
export const emailVerificationExpiration = 3600 * 1000
// email verification expiration in seconds (1 hour)
export const emailVerificationExpiration = 3600

// configuration of database in form of sequelize options
export const database: Options = {
Expand All @@ -54,3 +57,17 @@ export const database: Options = {
}

export const isBehindProxy = stringToBoolean(process.env.BEHIND_PROXY)

const stringToArray = (value: string | undefined) => {
if (!value) return []
return value.split(/\s*,\s*/)
}

export const allowedGroups = stringToArray(
process.env.ALLOWED_GROUPS ?? 'https://example.com#us',
)

export const jwt = {
key: process.env.JWT_KEY ?? './ecdsa-p256-private.pem',
alg: process.env.JWT_ALG ?? 'ES256',
}
Loading