Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3b3b91523 |
@@ -1,4 +1,4 @@
|
|||||||
FROM mirror.gcr.io/library/node:18-alpine as dev
|
FROM mirror.gcr.io/library/node:24-alpine as dev
|
||||||
RUN apk add netcat-openbsd
|
RUN apk add netcat-openbsd
|
||||||
|
|
||||||
RUN npm config set update-notifier false
|
RUN npm config set update-notifier false
|
||||||
@@ -12,7 +12,7 @@ RUN npm run compile
|
|||||||
|
|
||||||
ENTRYPOINT npm run start
|
ENTRYPOINT npm run start
|
||||||
|
|
||||||
FROM mirror.gcr.io/node:18-alpine AS prod
|
FROM mirror.gcr.io/node:24-alpine AS prod
|
||||||
RUN npm config set update-notifier false
|
RUN npm config set update-notifier false
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@@ -6,5 +6,8 @@
|
|||||||
"host": "HOSTNAME",
|
"host": "HOSTNAME",
|
||||||
"authentication": {
|
"authentication": {
|
||||||
"secret": "FEATHERS_SECRET"
|
"secret": "FEATHERS_SECRET"
|
||||||
|
},
|
||||||
|
"wildDuck": {
|
||||||
|
"url": "WILDDUCK_URL"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
5
config/development.json
Normal file
5
config/development.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"wildDuck": {
|
||||||
|
"url": "http://localhost:3031"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
mockserver:
|
||||||
|
image: mockserver/mockserver:5.15.0
|
||||||
|
ports:
|
||||||
|
- "3031:1080"
|
||||||
|
environment:
|
||||||
|
- MOCKSERVER_INITIALIZATION_JSON_PATH=/config/initializerJson.json
|
||||||
|
volumes:
|
||||||
|
- ./mockserver-config:/config
|
||||||
|
command: ["-serverPort", "1080", "-logLevel", "INFO"]
|
||||||
107
mockserver-config/initializerJson.json
Normal file
107
mockserver-config/initializerJson.json
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/users/dev-user/addresses"
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"headers": {
|
||||||
|
"Content-Type": [
|
||||||
|
"application/json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"success": true,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": "alias1@test-codemowers.eu",
|
||||||
|
"address": "alias1@test-codemowers.eu",
|
||||||
|
"main": false,
|
||||||
|
"user": "dev-user",
|
||||||
|
"tags": [
|
||||||
|
"color"
|
||||||
|
],
|
||||||
|
"created": "2023-01-01T00:00:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "alias2@test-codemowers.eu",
|
||||||
|
"address": "alias2@test-codemowers.eu",
|
||||||
|
"main": false,
|
||||||
|
"user": "dev-user",
|
||||||
|
"tags": [
|
||||||
|
"animal"
|
||||||
|
],
|
||||||
|
"created": "2023-01-02T00:00:00.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "alias3@test-codemowers.eu",
|
||||||
|
"address": "alias3@test-codemowers.eu",
|
||||||
|
"main": false,
|
||||||
|
"user": "dev-user",
|
||||||
|
"tags": [],
|
||||||
|
"created": "2023-01-03T00:00:00.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/users/dev-user/addresses"
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"headers": {
|
||||||
|
"Content-Type": [
|
||||||
|
"application/json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"success": true,
|
||||||
|
"id": "new-alias@test-codemowers.eu"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/addresses/resolve/.*"
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"headers": {
|
||||||
|
"Content-Type": [
|
||||||
|
"application/json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"success": true,
|
||||||
|
"user": "dev-user",
|
||||||
|
"address": "{{request.pathSegments.[2]}}",
|
||||||
|
"id": "{{request.pathSegments.[2]}}",
|
||||||
|
"main": false,
|
||||||
|
"tags": [],
|
||||||
|
"created": "2023-01-01T00:00:00.000Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "DELETE",
|
||||||
|
"path": "/users/dev-user/addresses/.*"
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"headers": {
|
||||||
|
"Content-Type": [
|
||||||
|
"application/json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
5607
package-lock.json
generated
5607
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@@ -20,7 +20,7 @@
|
|||||||
"contributors": [],
|
"contributors": [],
|
||||||
"bugs": {},
|
"bugs": {},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16.19.1"
|
"node": ">= 24"
|
||||||
},
|
},
|
||||||
"feathers": {
|
"feathers": {
|
||||||
"language": "ts",
|
"language": "ts",
|
||||||
@@ -39,16 +39,15 @@
|
|||||||
},
|
},
|
||||||
"main": "lib/index",
|
"main": "lib/index",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon -x ts-node src/index.ts",
|
"dev": "cross-env NODE_ENV=development nodemon -x ts-node src/index.ts",
|
||||||
"compile": "shx rm -rf lib/ && tsc",
|
"compile": "shx rm -rf lib/ && tsc",
|
||||||
"start": "node lib/",
|
"start": "node lib/",
|
||||||
"prettier": "npx prettier \"**/*.ts\" --write",
|
"prettier": "npx prettier \"**/*.ts\" --write",
|
||||||
"mocha": "cross-env NODE_ENV=test mocha test/ --require ts-node/register --recursive --extension .ts --exit",
|
"vitest": "vitest run",
|
||||||
"test": "npm run mocha",
|
"test": "npm run vitest"
|
||||||
"bundle:client": "npm run compile && npm pack --pack-destination ./public"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@faker-js/faker": "^8.0.2",
|
"@faker-js/faker": "^10.1.0",
|
||||||
"@feathersjs/adapter-commons": "^5.0.8",
|
"@feathersjs/adapter-commons": "^5.0.8",
|
||||||
"@feathersjs/authentication": "^5.0.8",
|
"@feathersjs/authentication": "^5.0.8",
|
||||||
"@feathersjs/authentication-client": "^5.0.8",
|
"@feathersjs/authentication-client": "^5.0.8",
|
||||||
@@ -61,11 +60,10 @@
|
|||||||
"@feathersjs/transport-commons": "^5.0.8",
|
"@feathersjs/transport-commons": "^5.0.8",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"config": "^3.3.9",
|
"config": "^4.1.1",
|
||||||
"connect-redis": "^7.1.0",
|
"connect-redis": "^7.1.0",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.17.3",
|
||||||
"ioredis": "^5.3.2",
|
|
||||||
"openid-client": "^5.6.5",
|
"openid-client": "^5.6.5",
|
||||||
"redis": "^4.6.7",
|
"redis": "^4.6.7",
|
||||||
"winston": "^3.10.0"
|
"winston": "^3.10.0"
|
||||||
@@ -76,21 +74,19 @@
|
|||||||
"@types/cookie-parser": "^1.4.3",
|
"@types/cookie-parser": "^1.4.3",
|
||||||
"@types/express-session": "^1.17.7",
|
"@types/express-session": "^1.17.7",
|
||||||
"@types/jsdom": "^27.0.0",
|
"@types/jsdom": "^27.0.0",
|
||||||
"@types/mocha": "^10.0.1",
|
"@types/node": "^25.0.1",
|
||||||
"@types/node": "^20.4.5",
|
|
||||||
"@types/redis": "^4.0.11",
|
|
||||||
"@types/sinon": "^21.0.0",
|
"@types/sinon": "^21.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^10.1.0",
|
||||||
"husky": "^8.0.3",
|
"husky": "^9.1.7",
|
||||||
"jsdom": "^27.0.1",
|
"jsdom": "^27.0.1",
|
||||||
"lint-staged": "^13.2.3",
|
"lint-staged": "^16.2.7",
|
||||||
"mocha": "^10.2.0",
|
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.1",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
"shx": "^0.3.4",
|
"shx": "^0.4.0",
|
||||||
"sinon": "^21.0.0",
|
"sinon": "^21.0.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.1.6"
|
"typescript": "^5.1.6",
|
||||||
|
"vitest": "^4.0.15"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{ts,js,css,md}": "prettier --write"
|
"*.{ts,js,css,md}": "prettier --write"
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ export class AliasesService<ServiceParams extends AliasesParams = AliasesParams>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getUserIdByEmailAddress(params: ServiceParams): Promise<string> {
|
private async getUserIdByEmailAddress(params: ServiceParams): Promise<string> {
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
return 'dev-user';
|
||||||
|
}
|
||||||
|
|
||||||
const emails = params.session?.user?.emails;
|
const emails = params.session?.user?.emails;
|
||||||
|
|
||||||
const preferredDomain = config.get('wildDuck.preferredDomain');
|
const preferredDomain = config.get('wildDuck.preferredDomain');
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ export class AuthOidcService<ServiceParams extends AuthOidcParams = AuthOidcPara
|
|||||||
constructor(public options: AuthOidcServiceOptions) {}
|
constructor(public options: AuthOidcServiceOptions) {}
|
||||||
|
|
||||||
async find(params: ServiceParams): Promise<AuthOidcResponse> {
|
async find(params: ServiceParams): Promise<AuthOidcResponse> {
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
// In dev mode, simulate login by setting fake user session
|
||||||
|
params.session.user = {
|
||||||
|
emails: ['dev@k-space.ee']
|
||||||
|
};
|
||||||
|
return '/';
|
||||||
|
}
|
||||||
|
|
||||||
const issuer = await Issuer.discover(config.get('oidc.gatewayUri'));
|
const issuer = await Issuer.discover(config.get('oidc.gatewayUri'));
|
||||||
const client = new issuer.Client({
|
const client = new issuer.Client({
|
||||||
client_id: config.get('oidc.clientId'),
|
client_id: config.get('oidc.clientId'),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import type { Server } from 'http';
|
import type { Server } from 'http';
|
||||||
|
import { describe, it, beforeAll, afterAll } from 'vitest';
|
||||||
import { app } from '../src/app';
|
import { app } from '../src/app';
|
||||||
|
|
||||||
const port = app.get('port');
|
const port = app.get('port');
|
||||||
@@ -10,11 +11,11 @@ const appUrl = `http://${app.get('host')}:${port}`;
|
|||||||
describe('Feathers application tests', () => {
|
describe('Feathers application tests', () => {
|
||||||
let server: Server;
|
let server: Server;
|
||||||
|
|
||||||
before(async () => {
|
beforeAll(async () => {
|
||||||
server = await app.listen(port);
|
server = await app.listen(port);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(async () => {
|
afterAll(async () => {
|
||||||
await app.teardown();
|
await app.teardown();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { describe, it, beforeAll } from 'vitest';
|
||||||
|
|
||||||
describe('UI tests', () => {
|
describe('UI tests', () => {
|
||||||
let html: string;
|
let html: string;
|
||||||
|
|
||||||
before(async () => {
|
beforeAll(async () => {
|
||||||
// Load the HTML file
|
// Load the HTML file
|
||||||
const htmlPath = path.join(__dirname, '../public/index.html');
|
const htmlPath = path.join(__dirname, '../public/index.html');
|
||||||
html = fs.readFileSync(htmlPath, 'utf8');
|
html = fs.readFileSync(htmlPath, 'utf8');
|
||||||
|
|||||||
9
vitest.config.ts
Normal file
9
vitest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
environment: 'node',
|
||||||
|
globals: true,
|
||||||
|
silent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user