Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8968e87
Remove build step for local development
anishapant21 Jan 30, 2026
e655774
Merge branch 'dev' into fixes/npm-start
anishapant21 Feb 18, 2026
d2113ec
Merge branch 'dev' into fixes/npm-start
anishapant21 Mar 8, 2026
e49a9db
Dev deployment workflow
anishapant21 Mar 9, 2026
8e21cff
Minor update
anishapant21 Mar 9, 2026
a6e0148
Merge branch 'fixes/npm-start' of github.com:mieweb/LDAPServer into f…
anishapant21 Mar 9, 2026
4f21b64
Update node version
anishapant21 Mar 9, 2026
c2665b6
Merge pull request #127 from mieweb/fixes/npm-start
anishapant21 Mar 9, 2026
610d60f
Merge branch 'dev' into chore/upgrade-node-24
anishapant21 Mar 9, 2026
bab40dd
Merge branch 'dev' into feature/dev-deployment
anishapant21 Mar 11, 2026
0983420
Add package lock
anishapant21 Mar 11, 2026
d77bb01
Update package lock
anishapant21 Mar 11, 2026
22b23ca
Merge pull request #148 from mieweb/chore/upgrade-node-24
anishapant21 Mar 11, 2026
b415b90
Add license
anishapant21 Mar 11, 2026
2fb5a09
Merge branch 'dev' into feature/dev-deployment
anishapant21 Mar 13, 2026
5367092
Merge pull request #147 from mieweb/feature/dev-deployment
anishapant21 Mar 13, 2026
399efb0
Minor fix
anishapant21 Mar 13, 2026
8694bd6
Merge pull request #152 from mieweb/fixes/gid-issue
anishapant21 Mar 13, 2026
1cf621b
Use hashed passwords
anishapant21 Mar 15, 2026
114c7b2
Merge pull request #153 from mieweb/fixes/sql-passwords
anishapant21 Mar 15, 2026
7e7ee67
Remove outdated workflow
anishapant21 Mar 15, 2026
71d7b4c
Merge branch 'dev' of github.com:mieweb/LDAPServer into dev
anishapant21 Mar 15, 2026
e2635ce
Merge branch 'dev' into docs/add-license
anishapant21 Mar 15, 2026
409ce21
Merge pull request #151 from mieweb/docs/add-license
anishapant21 Mar 16, 2026
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
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ This is a **modular LDAP gateway** built with Node.js and ldapjs that bridges LD
- **Local development**: Run `./launch.sh` (starts Docker MySQL/client, installs deps, runs server)
- **Stop services**: `./shutdown.sh` (kills Node process, stops Docker)
- **Testing**: `ldapsearch -x -H ldaps://localhost:636 -b "dc=mieweb,dc=com" "(uid=test)"` and `ssh test@localhost -p 2222`
- **Deployment**: Use Terraform in `terraform/` for AWS EC2 with security group (ports 22, 636, 3000)
- **Deployment**: Create a `dev-v*` GitHub release to auto-deploy to the dev container via SSH (see `.github/workflows/deploy-dev.yml`)

## Project-Specific Patterns
- **Backend separation**: Always implement both auth and directory providers (see `npm/src/interfaces/`)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
workflow_dispatch:

env:
NODE_VERSION: '18'
NODE_VERSION: '24'
REGISTRY_URL: 'https://registry.npmjs.org'

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [ main, dev ]

env:
NODE_VERSION: '18'
NODE_VERSION: '24'

jobs:
# Stage 1: Fast unit tests (fail fast)
Expand Down
186 changes: 186 additions & 0 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# ─────────────────────────────────────────────────────────
# Deploy to Development Container
#
# Triggers when a release with tag 'dev-v*' is created
# SSHs into the dev container, pulls latest code,
# builds, restarts the systemd service, and verifies health.
#
# Tags: dev-v1.2.3 → deploys to dev container
# v1.2.3 → skipped (handled by other workflows)
# ─────────────────────────────────────────────────────────

name: Deploy to Development Container

on:
release:
types: [created]

permissions:
contents: write

jobs:
# ─────────────────────────────────────────────
# Gate: Only run for dev-v* tags
# ─────────────────────────────────────────────
check-tag:
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.check.outputs.should_run }}
version: ${{ steps.check.outputs.version }}
tag_name: ${{ steps.check.outputs.tag_name }}
steps:
- name: Check tag pattern
id: check
run: |
TAG="${{ github.event.release.tag_name }}"
echo "tag_name=${TAG}" >> "$GITHUB_OUTPUT"

if [[ "$TAG" == dev-v* ]]; then
echo "should_run=true" >> "$GITHUB_OUTPUT"
VERSION="${TAG#dev-v}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "✅ Tag '${TAG}' matches dev-v* — deploying to development"
else
echo "should_run=false" >> "$GITHUB_OUTPUT"
echo "⏭️ Tag '${TAG}' does not match dev-v* — skipping"
fi

# ─────────────────────────────────────────────
# Build & test before deploying
# ─────────────────────────────────────────────
build-and-test:
needs: check-tag
if: needs.check-tag.outputs.should_run == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: dev

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build core package
run: npm run build:core

- name: Build server package
run: npm run build:server

- name: Generate test certificates
run: |
mkdir -p server/cert
openssl req -x509 -newkey rsa:2048 -nodes -sha256 \
-subj "/CN=localhost" \
-keyout server/cert/server.key \
-out server/cert/server.crt \
-days 1

- name: Run core tests
run: npm run test:core

- name: Run server tests
run: npm run test:server

# ─────────────────────────────────────────────
# Deploy to dev container via SSH
# ─────────────────────────────────────────────
deploy-dev:
needs: [check-tag, build-and-test]
if: needs.check-tag.outputs.should_run == 'true'
runs-on: ubuntu-latest
environment: development
env:
VERSION: ${{ needs.check-tag.outputs.version }}
TAG_NAME: ${{ needs.check-tag.outputs.tag_name }}
steps:
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEV_CONTAINER_SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key

# Add known hosts to prevent interactive prompt
if [ -n "${{ secrets.DEV_CONTAINER_SSH_KNOWN_HOSTS }}" ]; then
echo "${{ secrets.DEV_CONTAINER_SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts
fi

- name: Deploy to development container
run: |
ssh -i ~/.ssh/deploy_key \
-p ${{ secrets.DEV_CONTAINER_PORT }} \
-o StrictHostKeyChecking=no \
${{ secrets.DEV_CONTAINER_USER }}@${{ secrets.DEV_CONTAINER_HOST }} << 'DEPLOY_SCRIPT'
set -e

echo "======================================"
echo "Deploying LDAP Gateway ${{ env.TAG_NAME }}"
echo "======================================"

echo "==> Pulling latest code from dev branch"
cd /opt/ldap-gateway
git fetch origin dev
git checkout dev
git reset --hard origin/dev

echo "==> Current commit:"
git log -1 --oneline

echo "==> Installing dependencies"
npm ci --production=false

echo "==> Building core package"
npm run build:core

echo "==> Building server package"
npm run build:server

echo "==> Restarting LDAP Gateway service"
sudo systemctl restart ldap-gateway

echo "==> Waiting for service to start"
sleep 5

echo "==> Health check"
if sudo systemctl is-active --quiet ldap-gateway; then
echo "✅ LDAP Gateway is running"
sudo systemctl status ldap-gateway --no-pager --lines=10
else
echo "❌ LDAP Gateway failed to start"
sudo journalctl -u ldap-gateway --no-pager -n 50
exit 1
fi

echo "======================================"
echo "✅ Deployment complete"
echo "======================================"
DEPLOY_SCRIPT

- name: Update release with deployment status
if: always()
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.TAG_NAME }}
name: "LDAP Gateway Dev ${{ env.TAG_NAME }}"
body: |
## LDAP Gateway Development Release

**Version:** `${{ env.VERSION }}`
**Environment:** Development
**Status:** ${{ job.status == 'success' && '✅ Deployed' || '❌ Failed' }}
**Branch:** `dev`

### Deployment Details
- Build & Tests: ${{ needs.build-and-test.result == 'success' && '✅ Passed' || '❌ Failed' }}
- Container Deploy: ${{ job.status == 'success' && '✅ Completed' || '❌ Failed' }}

---
*Automated deployment via GitHub Actions*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 changes: 0 additions & 45 deletions .github/workflows/prod.yml

This file was deleted.

21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024-2026 Medical Informatics Engineering (MIE)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 2 additions & 2 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const providers = {

#### Old Dockerfile Pattern
```dockerfile
FROM node:18
FROM node:24
COPY src/ /app/src/
COPY package.json /app/
RUN npm install
Expand All @@ -168,7 +168,7 @@ CMD ["node", "src/server.js"]

#### New Dockerfile Pattern
```dockerfile
FROM node:18
FROM node:24
# Option 1: Use binary release
COPY ldap-gateway /usr/local/bin/
CMD ["ldap-gateway"]
Expand Down
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,14 @@ AD_DOMAIN=your-domain.com
LDAP_BIND_DN=CN=service,DC=your-domain,DC=com
SQL_URL=mysql://ldap_user:secure_password@localhost:3306/your_database
SQL_QUERY_ONE_USER='SELECT * FROM users WHERE username = ?'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM groups g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM `groups` g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_ALL_USERS='SELECT * FROM users'
SQL_QUERY_ALL_GROUPS='SELECT
g.gid_number,
g.name,
g.gid_number AS id,
GROUP_CONCAT(u.username) AS member_uids
FROM groups g
FROM `groups` g
LEFT JOIN user_groups ug ON g.gid_number = ug.group_id
LEFT JOIN users u ON ug.user_id = u.id
GROUP BY g.gid_number, g.name
Expand All @@ -312,14 +312,14 @@ DIRECTORY_BACKEND=mysql # User info from MySQL
AUTH_BACKENDS=mysql # Passwords in MySQL
SQL_URL=mysql://ldap_user:secure_password@localhost:3306/your_database
SQL_QUERY_ONE_USER='SELECT * FROM users WHERE username = ?'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM groups g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM `groups` g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_ALL_USERS='SELECT * FROM users'
SQL_QUERY_ALL_GROUPS='SELECT
g.gid_number,
g.name,
g.gid_number AS id,
GROUP_CONCAT(u.username) AS member_uids
FROM groups g
FROM `groups` g
LEFT JOIN user_groups ug ON g.gid_number = ug.group_id
LEFT JOIN users u ON ug.user_id = u.id
GROUP BY g.gid_number, g.name
Expand Down Expand Up @@ -351,14 +351,14 @@ DIRECTORY_BACKEND=sql # User info from SQL
AUTH_BACKENDS=sql,ldap # Try SQL auth first, fallback to LDAP
SQL_URL=mysql://ldap_user:secure_password@localhost:3306/your_database
SQL_QUERY_ONE_USER='SELECT * FROM users WHERE username = ?'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM groups g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM `groups` g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_ALL_USERS='SELECT * FROM users'
SQL_QUERY_ALL_GROUPS='SELECT
g.gid_number,
g.name,
g.gid_number AS id,
GROUP_CONCAT(u.username) AS member_uids
FROM groups g
FROM `groups` g
LEFT JOIN user_groups ug ON g.gid_number = ug.group_id
LEFT JOIN users u ON ug.user_id = u.id
GROUP BY g.gid_number, g.name
Expand All @@ -375,14 +375,14 @@ AD_DOMAIN=your-domain.com
LDAP_BIND_DN=CN=service,DC=your-domain,DC=com
SQL_URL=mysql://ldap_user:secure_password@localhost:3306/your_database
SQL_QUERY_ONE_USER='SELECT * FROM users WHERE username = ?'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM groups g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_GROUPS_BY_MEMBER='SELECT * FROM `groups` g WHERE JSON_CONTAINS(g.member_uids, JSON_QUOTE(?))'
SQL_QUERY_ALL_USERS='SELECT * FROM users'
SQL_QUERY_ALL_GROUPS='SELECT
g.gid_number,
g.name,
g.gid_number AS id,
GROUP_CONCAT(u.username) AS member_uids
FROM groups g
FROM `groups` g
LEFT JOIN user_groups ug ON g.gid_number = ug.group_id
LEFT JOIN users u ON ug.user_id = u.id
GROUP BY g.gid_number, g.name
Expand Down Expand Up @@ -575,10 +575,11 @@ LDAPServer/
# Install dependencies
npm install

# Build core package
npm run build:core
# Start the server (no build required for local development)
npm start

# Build server package
# Build for releases (only needed for npm publishing and distribution packages)
npm run build:core
npm run build:server

# Create binary
Expand Down
Loading
Loading