Skip to content
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
18 changes: 18 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
NGINX_PORT1=22212
NGINX_PORT2=22213
NGINX_PORT3=22214
NGINX_PORT4=22215

DEV_API_PORT=22222
DEV_UI_PORT=22223
DEV_OBSERVER_PORT=22224
MAILDEV_UI_PORT=22225
MAILDEV_SMTP_PORT=22226

MONGO_PORT=22232
LDAP_PORT=22233
LDAP_ADMIN_PORT=22235
OIDC_PROVIDER_PORT=22236
KEYCLOAK_PORT=22237

EVENTS_PORT=22242
2 changes: 1 addition & 1 deletion .zellij.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ layout {
}
pane size=1 borderless=true {
command "bash"
args "-ic" "echo -n -e \"Dev server available at \\e[1;96mhttp://localhost:5689\\033[0m\""
args "-ic" "echo -n -e \"Dev server available at \\e[1;96mhttp://localhost:$NGINX_PORT\\033[0m\""
}
}
12 changes: 4 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ Run the 2 development servers with these commands et separate shells:
npm run dev-server
npm run dev-client

When both servers are ready, go to [http://localhost:5689](http://localhost:5689).

Test the multi-site mode:

curl -H "Content-Type: application/json" -XPOST "http://localhost:5689/simple-directory/api/sites?key=secret-sites" -d '{"_id":"devsite","owner":{"type":"organization","id":"admins-org","name":"Admins organization"},"host":"localhost:5989","theme":{"primaryColor":"#004D40"}}'
curl -H "Content-Type: application/json" -XPOST "http://localhost:5689/simple-directory/api/sites?key=secret-sites" -d '
{"_id":"devsite2","owner":{"type":"organization","id":"admins-org","name":"Admins organization"},"host":"localhost:5999","theme":{"primaryColor":"#FF4D40"}}'

## Docker image

Test building the docker image:
Expand All @@ -44,6 +36,10 @@ docker build --progress=plain -t sd-dev .
docker run --network=host --env PORT=8081 sd-dev
```

## Working with Git Worktrees

This project supports git worktrees with fully isolated port allocations, allowing multiple branches to run concurrently (useful for AI agents or parallel development). Run `./dev/worktree.sh <branch-name>` to create a new worktree with its own `.env`, Docker Compose project, and randomized port range. When setting up for the first time, not in a worktree, you can run `./dev/init-env.sh`.

## Git quality checks

This project uses [husky](https://typicode.github.io/husky/) and to ensure quality of commits. The pre-commit hook runs the docker image build, this way we get linting, testing, and building all checked in 1 step.
Expand Down
10 changes: 2 additions & 8 deletions api/config/default.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -271,18 +271,12 @@ module.exports = {
locales: ['fr', 'en', 'es', 'pt', 'it', 'de']
},
mails: {
from: 'no-reply@test.com',
// from: 'no-reply@test.com'
// transport is a full configuration object for createTransport of nodemailer
// cf https://nodemailer.com/smtp/
transport: {
port: 1025,
ignoreTLS: true,
host: 'localhost'
},
extraParams: {}
transport: {}
},
maildev: {
url: 'http://localhost:1080',
active: false
},
quotas: {
Expand Down
37 changes: 27 additions & 10 deletions api/config/development.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
require('dotenv').config({ quiet: true })

if (!process.env.DEV_API_PORT) throw new Error('missing DEV_API_PORT env variable, use "source dev/init-env.sh" to init .env file')

module.exports = {
mongo: {
url: 'mongodb://localhost:27017/simple-directory-' + (process.env.NODE_ENV || 'development')
url: 'mongodb://localhost:' + process.env.MONGO_PORT + '/simple-directory-' + (process.env.NODE_ENV || 'development')
},
port: 5690,
publicUrl: 'http://localhost:5689/simple-directory',
port: process.env.DEV_API_PORT,
publicUrl: 'http://localhost:' + process.env.NGINX_PORT1 + '/simple-directory',
// use this host when debugging a data-fair inside a virtualbox vm
// publicUrl: 'http://10.0.2.2:5689',
admins: ['alban.mouton@koumoul.com', 'alban.mouton@gmail.com', 'superadmin@test.com', 'admin@test.com'],
Expand Down Expand Up @@ -32,8 +36,18 @@ module.exports = {
i18n: {
// defaultLocale: 'en'
},
mails: {
from: 'no-reply@test.com',
transport: {
port: parseInt(process.env.MAILDEV_SMTP_PORT || '1025'),
ignoreTLS: true,
host: 'localhost'
},
extraParams: {}
},
maildev: {
active: true
active: true,
url: 'http://localhost:' + (process.env.MAILDEV_UI_PORT),
},
storage: {
type: 'mongo',
Expand All @@ -43,7 +57,7 @@ module.exports = {
organizations: './dev/resources/organizations.json'
},
ldap: {
url: 'ldap://localhost:389',
url: 'ldap://localhost:' + process.env.LDAP_PORT,
searchUserDN: 'cn=admin,dc=example,dc=org',
searchUserPassword: 'admin',
cacheMS: 1000,
Expand Down Expand Up @@ -104,8 +118,8 @@ module.exports = {
sites: 'secret-sites'
},
perOrgStorageTypes: ['ldap'],
cipherPassword: 'SiK7LwFcuYnktJuxcNaF/Q==',
privateEventsUrl: 'http://localhost:8088',
cipherPassword: 'test',
privateEventsUrl: 'http://localhost:' + process.env.EVENTS_PORT,
plannedDeletionDelay: 1,
cleanup: {
cron: '*/1 * * * *',
Expand Down Expand Up @@ -159,7 +173,7 @@ module.exports = {
title: 'Test OIDC IDP',
color: '#D92929',
img: 'https://cdn-icons-png.flaticon.com/512/25/25231.png',
discovery: 'http://localhost:9009/.well-known/openid-configuration',
discovery: 'http://localhost:' + process.env.OIDC_PROVIDER_PORT + '/.well-known/openid-configuration',
client: {
id: 'foo',
secret: 'bar'
Expand Down Expand Up @@ -193,7 +207,7 @@ module.exports = {
title: 'Test OIDC Keycloak',
color: '#D92929',
img: 'https://upload.wikimedia.org/wikipedia/commons/2/29/Keycloak_Logo.png',
discovery: 'http://localhost:8888/realms/master/.well-known/openid-configuration',
discovery: 'http://localhost:' + process.env.KEYCLOAK_PORT + '/realms/master/.well-known/openid-configuration',
client: {
id: 'test-sd',
secret: 'x17YcfoJRPPrZoiXFTBwhWxSJGwTa5bi'
Expand Down Expand Up @@ -224,5 +238,8 @@ module.exports = {
},
siteOrgs: true,
siteAdmin: true,
multiRoles: true
multiRoles: true,
observer: {
port: process.env.DEV_OBSERVER_PORT
}
}
27 changes: 21 additions & 6 deletions api/config/test.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
require('dotenv').config({ quiet: true })

if (!process.env.DEV_API_PORT) throw new Error('missing DEV_API_PORT env variable, use "source dev/init-env.sh" to init .env file')

module.exports = {
mongo: {
url: 'mongodb://localhost:27017/data-fair-' + (process.env.NODE_ENV || 'test')
url: 'mongodb://localhost:' + process.env.MONGO_PORT + '/simple-directory-' + (process.env.NODE_ENV || 'development')
},
port: 5690,
publicUrl: 'http://localhost:5689/simple-directory',
port: process.env.DEV_API_PORT,
publicUrl: 'http://localhost:' + process.env.NGINX_PORT1 + '/simple-directory',
admins: ['admin@test.com'],
adminCredentials: {
email: '_superadmin@test.com',
Expand All @@ -25,7 +29,7 @@ module.exports = {
},
mongo: {},
ldap: {
url: 'ldap://localhost:389',
url: 'ldap://localhost:' + process.env.LDAP_PORT,
cacheMS: 0,
searchUserDN: 'cn=admin,dc=example,dc=org',
searchUserPassword: 'admin',
Expand Down Expand Up @@ -68,14 +72,25 @@ module.exports = {
duration: 60
},
perOrgStorageTypes: ['ldap'],
mails: {
from: 'no-reply@test.com',
transport: {
port: parseInt(process.env.MAILDEV_SMTP_PORT || '1025'),
ignoreTLS: true,
host: 'localhost'
},
extraParams: {}
},
maildev: {
active: true
active: true,
url: 'http://localhost:' + (process.env.MAILDEV_UI_PORT),
},
manageSites: true,
managePartners: true,
cipherPassword: 'test',
observer: {
active: false
active: false,
port: process.env.DEV_OBSERVER_PORT
},
passwordValidation: {
entropy: 40,
Expand Down
3 changes: 3 additions & 0 deletions api/src/storages/ldap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ export class LdapStorage implements SdStorage {
private organizationCaptureRegex: RegExp | undefined

constructor (params: LdapParams, org?: Organization) {
if (process.env.NODE_ENV === 'test') {
params.url = params.url.replace('{LDAP_PORT}', process.env.LDAP_PORT!)
}
this.ldapParams = params
this.org = org
console.log('Connecting to ldap ' + params.url)
Expand Down
29 changes: 29 additions & 0 deletions dev/delete-worktree.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

BRANCH_NAME=$1

if [ -z "$BRANCH_NAME" ]; then
echo "Error: Please provide a branch name."
echo "Usage: ./dev/delete-worktree.sh feat-xyz"
exit 1
fi

REPO_NAME=$(basename "$PWD")
TARGET_DIR="../${REPO_NAME}_${BRANCH_NAME}"

if [ ! -d "$TARGET_DIR" ]; then
echo "Error: Worktree directory $TARGET_DIR does not exist."
exit 1
fi

echo "Stopping docker compose services in $TARGET_DIR"
cd "$TARGET_DIR"
docker compose --profile dev down

echo "Removing git worktree at $TARGET_DIR"
cd "$PWD"
git worktree remove "$TARGET_DIR"

echo "-----------------------------------------------"
echo "✅ Worktree $BRANCH_NAME deleted!"
echo "-----------------------------------------------"
25 changes: 25 additions & 0 deletions dev/init-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

RANDOM_NB=$((1024 + RANDOM % 48000))
echo "Use random base port $RANDOM_NB"

cat <<EOF > ".env"
NGINX_PORT1=$((RANDOM_NB))
NGINX_PORT2=$((RANDOM_NB + 1))
NGINX_PORT3=$((RANDOM_NB + 2))
NGINX_PORT4=$((RANDOM_NB + 3))

DEV_API_PORT=$((RANDOM_NB + 10))
DEV_UI_PORT=$((RANDOM_NB + 11))
DEV_OBSERVER_PORT=$((RANDOM_NB + 12))
MAILDEV_UI_PORT=$((RANDOM_NB + 13))
MAILDEV_SMTP_PORT=$((RANDOM_NB + 14))

MONGO_PORT=$((RANDOM_NB + 20))
LDAP_PORT=$((RANDOM_NB + 21))
LDAP_ADMIN_PORT=$((RANDOM_NB + 22))
OIDC_PROVIDER_PORT=$((RANDOM_NB + 23))
KEYCLOAK_PORT=$((RANDOM_NB + 24))

EVENTS_PORT=$((RANDOM_NB + 30))
EOF
Loading