diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index b5c64d3..6801458 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -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/`) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 40fd31e..23d0fcb 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -9,7 +9,7 @@ on: workflow_dispatch: env: - NODE_VERSION: '18' + NODE_VERSION: '24' REGISTRY_URL: 'https://registry.npmjs.org' jobs: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81ef4cc..6090b06 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: branches: [ main, dev ] env: - NODE_VERSION: '18' + NODE_VERSION: '24' jobs: # Stage 1: Fast unit tests (fail fast) diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml new file mode 100644 index 0000000..b7d07a1 --- /dev/null +++ b/.github/workflows/deploy-dev.yml @@ -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 }} diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml deleted file mode 100644 index 022d25b..0000000 --- a/.github/workflows/prod.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Build and Upload LDAP Server on Release - -on: - release: - types: [created] - -permissions: - contents: write - -jobs: - build-server: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 18 - - - name: Install dependencies - run: | - cd src - npm install - - - name: Prepare build directory - run: | - mkdir build - cp -r src/* build/ - - - name: Copy .env.example to build folder - run: cp src/.env.example build/ - - - name: Create tarball - run: | - tar -czf ldap-server.tar.gz -C build . - - - name: Upload tarball to GitHub release - uses: softprops/action-gh-release@v1 - with: - files: ldap-server.tar.gz - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6a4dd56 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/MIGRATION.md b/MIGRATION.md index 39add28..1025736 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -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 @@ -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"] diff --git a/README.md b/README.md index af95112..d22334f 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/deploy.yml b/deploy.yml deleted file mode 100644 index d52cb36..0000000 --- a/deploy.yml +++ /dev/null @@ -1,134 +0,0 @@ -name: Deploy LDAP Node.js Server - -on: - pull_request: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - environment: dev - - steps: - - name: Checkout the repository - uses: actions/checkout@v2 - - - name: Set up Terraform - uses: hashicorp/setup-terraform@v2 - with: - terraform_version: 1.3.0 - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 - - - name: Fetch AMI ID for Amazon Linux - id: fetch_ami - run: | - os_filter="al2023-ami-*-x86_64" - owners="137112412989" # Amazon Linux owner ID - - ami_id=$(aws ec2 describe-images \ - --filters "Name=name,Values=$os_filter" "Name=state,Values=available" \ - --owners $owners \ - --query "Images | sort_by(@, &CreationDate)[-1].ImageId" \ - --output text) - - if [ -z "$ami_id" ]; then - echo "Failed to find valid AMI ID" - exit 1 - fi - - echo "ami_id=$ami_id" >> "$GITHUB_ENV" - - - name: Initialize Terraform - run: cd terraform && terraform init - - - name: Apply Terraform Configuration - run: | - cd terraform - terraform apply -auto-approve -var="ami_id=${{ env.ami_id }}" - - - name: Fetch EC2 Instance Public IP - id: get-ec2-ip - run: | - # Get the most recent instance with the LDAPServer tag - IP=$(aws ec2 describe-instances \ - --filters "Name=tag:Name,Values=LDAPServer" "Name=instance-state-name,Values=running" \ - --query "Reservations[*].Instances[*].[LaunchTime,PublicIpAddress]" \ - --output text | sort -r | head -n 1 | awk '{print $2}') - - # Check if we got a valid IP - if [[ -z "$IP" ]]; then - echo "Error: Could not find running instance with tag LDAPServer" - exit 1 - fi - - # Set the environment variable correctly - echo "EC2_IP=${IP}" >> $GITHUB_ENV - echo "Found IP: ${IP}" - - - name: Wait for EC2 to be ready - run: sleep 55 # Ensure system is ready - - - name: Create .env file locally - run: | - cat > .env << EOF - DB_TYPE=${{ vars.DB_TYPE }} - MONGO_URI=${{ secrets.MONGO_URI }} - MONGO_DATABASE=${{ vars.MONGO_DATABASE }} - LDAP_BASE_DN=${{ vars.LDAP_BASE_DN }} - LDAP_PORT=${{ vars.LDAP_PORT }} - LDAP_CERT_CONTENT="${{ secrets.LDAP_CERT_CONTENT }}" - LDAP_KEY_CONTENT="${{ secrets.LDAP_KEY_CONTENT }}" - LDAP_URL=${{ secrets.LDAP_URL }} - EOF - - echo "Created .env file" - - - name: Deploy app to EC2 - run: | - echo "${{ secrets.EC2_PRIVATE_KEY }}" > ec2-key.pem - chmod 600 ec2-key.pem - - # First, clone the repository and set up the directory - ssh -o StrictHostKeyChecking=no -i ec2-key.pem ec2-user@${{ env.EC2_IP }} << 'EOSSH' - # Clone the repository - if [ -d "/home/ec2-user/LDAPServer" ]; then - rm -rf /home/ec2-user/LDAPServer - fi - git clone https://github.com/anishapant21/LDAPServer.git /home/ec2-user/LDAPServer - EOSSH - - # Now copy the .env file to the server - place it in the src directory - scp -o StrictHostKeyChecking=no -i ec2-key.pem .env ec2-user@${{ env.EC2_IP }}:/home/ec2-user/LDAPServer/src/.env - - # Finally, install dependencies and start the server - ssh -o StrictHostKeyChecking=no -i ec2-key.pem ec2-user@${{ env.EC2_IP }} << 'EOSSH' - # Install dependencies and start the Node.js server - cd /home/ec2-user/LDAPServer/src - npm install - - # Kill any existing node process - pkill -f "node server.js" || true - - # Start the server (already in the src directory) - nohup sudo node server.js > server.log 2>&1 & - - # Verify the server has started - sleep 5 - if pgrep -f "node server.js" > /dev/null; then - echo "Server started successfully" - ps aux | grep "node server.js" | grep -v grep - else - echo "Server failed to start" - tail -n 20 server.log - fi - EOSSH - - - name: Output EC2 Instance Public IP - run: echo "LDAP Server running at http://${{ env.EC2_IP }}" \ No newline at end of file diff --git a/docker/sql/init.sql b/docker/sql/init.sql index 94da52c..581ae39 100644 --- a/docker/sql/init.sql +++ b/docker/sql/init.sql @@ -33,11 +33,11 @@ CREATE TABLE IF NOT EXISTS users ( -- 4. Now insert users (gid_number matches existing groups) INSERT INTO users (username, password, full_name, email, uid_number, gid_number, home_directory) VALUES - ('ann', 'maya', 'Ann', 'ann@mieweb.com', 1001, 1001, '/home/ann'), - ('abrol','abrol', 'Abrol', 'abrol@mieweb.com', 1002, 1002, '/home/abrol'), - ('evan', 'evan', 'Evan Pant', 'evan@mieweb.com', 1003, 1003, '/home/evan'), - ('hrits', 'maya','Hrits Pant', 'hrits@mieweb.com', 1004, 1004, '/home/hrits'), - ('chris', 'chris','Chris Evans', 'chris@mieweb.com', 1005, 1005, '/home/chris'); + ('ann', '$6$Zmtz1yzJJyslWIK/$OoLdG1FNvPbSsyqekHGNIKdx.X1IlMQBVqACvr/WI8IFze.jzvLDzB1y3/Tigjk1mzcGKgowZ1lwCVF8EXv2q.', 'Ann', 'ann@mieweb.com', 1001, 1001, '/home/ann'), + ('abrol','$6$7KbEtgYeI.FFS7sw$EcFip4Ros8inRQQ2nGhBa32s3qA7h2pFXGfrP8x0NRMIM0bGaZ8bIObVh207yhQ.YW1KkMW2o7RIkEuDWG3wb/', 'Abrol', 'abrol@mieweb.com', 1002, 1002, '/home/abrol'), + ('evan', '$6$KgsRsEVt9N7AdBp9$/IKH6FUhKEu2PwwuzD9X.bhg3omjHvu2C4svEnJiIA3qxBnxf8PlLaZyRfcp8VRLwpOJcXKrj90OYw9rKJnq4/', 'Evan Pant', 'evan@mieweb.com', 1003, 1003, '/home/evan'), + ('hrits', '$6$Zmtz1yzJJyslWIK/$OoLdG1FNvPbSsyqekHGNIKdx.X1IlMQBVqACvr/WI8IFze.jzvLDzB1y3/Tigjk1mzcGKgowZ1lwCVF8EXv2q.','Hrits Pant', 'hrits@mieweb.com', 1004, 1004, '/home/hrits'), + ('chris', '$6$IgTXizGU8TCQg6fW$EQPpKK1lzLmr3x1HeZArvWQ3lLknQ60cPnKv6diDJVaaTaY7HLDPfrdfKcXYFE9IiSr3gBv98NodNb8ZCfAQD/','Chris Evans', 'chris@mieweb.com', 1005, 1005, '/home/chris'); -- 5. Add secondary groups INSERT INTO `groups` (gid_number, name, description, member_uids) VALUES @@ -51,7 +51,7 @@ CREATE TABLE IF NOT EXISTS user_groups ( group_id INT, PRIMARY KEY (user_id, group_id), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, - FOREIGN KEY (group_id) REFERENCES `groups`(gid) ON DELETE CASCADE + FOREIGN KEY (group_id) REFERENCES `groups`(gid_number) ON DELETE CASCADE ); INSERT INTO user_groups (user_id, group_id) diff --git a/homebrew/ldap-gateway.rb b/homebrew/ldap-gateway.rb index 0036f66..3cd52be 100644 --- a/homebrew/ldap-gateway.rb +++ b/homebrew/ldap-gateway.rb @@ -5,7 +5,7 @@ class LdapGateway < Formula sha256 "PLACEHOLDER_SHA256" license "MIT" - depends_on "node@18" + depends_on "node@24" def install # Install all files to libexec diff --git a/nfpm/nfpm.yaml b/nfpm/nfpm.yaml index 2ef385a..1966c6e 100644 --- a/nfpm/nfpm.yaml +++ b/nfpm/nfpm.yaml @@ -27,7 +27,7 @@ homepage: "https://github.com/mieweb/LDAPServer" license: "MIT" depends: - - nodejs (>= 18.0.0) + - nodejs (>= 24.0.0) provides: - ldap-gateway @@ -76,9 +76,9 @@ deb: overrides: deb: depends: - - nodejs (>= 18.0.0) + - nodejs (>= 24.0.0) - systemd rpm: depends: - - nodejs >= 18.0.0 + - nodejs >= 24.0.0 - systemd diff --git a/npm/package.json b/npm/package.json index 4dc92f9..e278d02 100644 --- a/npm/package.json +++ b/npm/package.json @@ -2,18 +2,16 @@ "name": "@ldap-gateway/core", "version": "0.1.0", "description": "Reusable LDAP gateway core with pluggable authentication and directory backends", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "src/index.js", "files": [ - "dist/", + "src/", "README.md" ], "scripts": { "build": "node build.js", "test": "jest", "test:watch": "jest --watch", - "test:coverage": "jest --coverage", - "prepublishOnly": "npm run build" + "test:coverage": "jest --coverage" }, "keywords": [ "ldap", @@ -25,7 +23,7 @@ "author": "MieWeb", "license": "MIT", "engines": { - "node": ">=18.0.0" + "node": ">=24.0.0" }, "peerDependencies": { "@ldapjs/controls": "git+https://github.com/mieweb/controls.git", diff --git a/package-lock.json b/package-lock.json index b21c3bc..65340e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,8 @@ "sqlite3": "5.1.7" }, "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0" + "node": ">=24.0.0", + "npm": ">=10.0.0" } }, "node_modules/@babel/code-frame": { @@ -3026,6 +3026,16 @@ "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", "license": "MIT" }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/end-of-stream": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", @@ -3650,6 +3660,19 @@ "ms": "^2.0.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -7013,7 +7036,7 @@ "jest": "30.2.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=24.0.0" }, "peerDependencies": { "@ldapjs/controls": "git+https://github.com/mieweb/controls.git", @@ -7051,8 +7074,8 @@ "sqlite": "5.1.1" }, "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0" + "node": ">=24.0.0", + "npm": ">=10.0.0" } }, "server/node_modules/@mongodb-js/saslprep": { diff --git a/package.json b/package.json index b6fca67..21642f2 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "server" ], "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0" + "node": ">=24.0.0", + "npm": ">=10.0.0" }, "scripts": { "build": "npm run build --workspaces", @@ -25,5 +25,6 @@ "pg": "8.16.3", "sqlite3": "5.1.7" }, - "description": "LDAP Gateway - Monorepo with reusable core and standalone server" + "description": "LDAP Gateway - Monorepo with reusable core and standalone server", + "license": "MIT" } \ No newline at end of file diff --git a/server/.env.example b/server/.env.example index 92b4b2a..0317145 100644 --- a/server/.env.example +++ b/server/.env.example @@ -58,9 +58,9 @@ LDAP_BASE_DN=dc=localhost # Supports MySQL, MariaDB, PostgreSQL, SQLite3 SQL_URL=mysql://root:rootpassword@localhost:3306/ldap_user_db 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 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 ORDER BY g.name' +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 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 ORDER BY g.name' # MongoDB Configuration (for mongodb auth/directory backends) MONGO_URI=mongodb://localhost:27017/ldap_user_db diff --git a/server/package.json b/server/package.json index 76a2b5d..08c220d 100644 --- a/server/package.json +++ b/server/package.json @@ -1,9 +1,10 @@ { "name": "ldap-gateway-server", "version": "1.0.0", + "license": "MIT", "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0" + "node": ">=24.0.0", + "npm": ">=10.0.0" }, "main": "serverMain.js", "bin": { diff --git a/server/test/e2e/Dockerfile.server b/server/test/e2e/Dockerfile.server index a813038..d7ecb16 100644 --- a/server/test/e2e/Dockerfile.server +++ b/server/test/e2e/Dockerfile.server @@ -1,4 +1,4 @@ -FROM node:18-slim AS builder +FROM node:24-slim AS builder WORKDIR /app @@ -28,7 +28,7 @@ WORKDIR /app/server RUN npm install --no-audit --no-fund COPY server ./ -FROM node:18-slim +FROM node:24-slim COPY --from=builder /app /app WORKDIR /app/server EXPOSE 636 diff --git a/terraform/main.tf b/terraform/main.tf deleted file mode 100644 index f8bec96..0000000 --- a/terraform/main.tf +++ /dev/null @@ -1,62 +0,0 @@ -resource "aws_security_group" "ldap_sg" { - name = "ldap-security-group" - description = "Allow LDAP, API, and SSH (for deployments)" - - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 636 - to_port = 636 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - from_port = 3000 - to_port = 3000 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } -} - -resource "aws_instance" "ldap_server" { - ami = var.ami_id - instance_type = var.instance_type - key_name = var.key_name - security_groups = [aws_security_group.ldap_sg.name] - - tags = { - Name = "LDAPServer" - } - - lifecycle { - create_before_destroy = true - } - - user_data = <<-EOF - #!/bin/bash - sudo yum update -y - sudo yum install -y git - curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash - - sudo yum install -y nodejs - - if [ -d "/home/ec2-user/LDAPServer" ]; then - sudo rm -rf /home/ec2-user/LDAPServer - fi - - sudo mkdir -p /home/ec2-user/LDAPServer - sudo chown -R ec2-user:ec2-user /home/ec2-user/LDAPServer - EOF -} \ No newline at end of file diff --git a/terraform/outputs.tf b/terraform/outputs.tf deleted file mode 100644 index bf665b8..0000000 --- a/terraform/outputs.tf +++ /dev/null @@ -1,3 +0,0 @@ -output "ldap_server_public_ip" { - value = aws_instance.ldap_server.public_ip -} \ No newline at end of file diff --git a/terraform/provider.tf b/terraform/provider.tf deleted file mode 100644 index 2a5ccf3..0000000 --- a/terraform/provider.tf +++ /dev/null @@ -1,3 +0,0 @@ -provider "aws" { - region = var.aws_region -} \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf deleted file mode 100644 index 87f81dd..0000000 --- a/terraform/variables.tf +++ /dev/null @@ -1,24 +0,0 @@ -variable "aws_region" { - default = "us-east-1" -} - -variable "instance_type" { - default = "t2.micro" -} - -variable "os_filter" { - default = "al2023-ami-*-x86_64" -} - -variable "ami_id" { - description = "The AMI ID to use for the EC2 instance" - type = string -} - -variable "owners" { - default = "137112412989" # Amazon Linux owner ID -} - -variable "key_name" { - default = "mietest" -} \ No newline at end of file