{"id":41824692,"url":"https://github.com/sasjs/server","last_synced_at":"2026-01-25T08:07:18.666Z","repository":{"id":37008409,"uuid":"375244404","full_name":"sasjs/server","owner":"sasjs","description":"Build Apps on Base SAS","archived":false,"fork":false,"pushed_at":"2025-12-21T01:27:39.000Z","size":6707,"stargazers_count":21,"open_issues_count":22,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-22T22:48:21.002Z","etag":null,"topics":["sas","sasjs"],"latest_commit_sha":null,"homepage":"https://server.sasjs.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sasjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["sasjs"]}},"created_at":"2021-06-09T06:05:56.000Z","updated_at":"2025-12-21T01:27:41.000Z","dependencies_parsed_at":"2023-11-08T03:52:53.752Z","dependency_job_id":"e9dec1d8-5141-471a-9688-cfe0d55a4304","html_url":"https://github.com/sasjs/server","commit_stats":null,"previous_names":[],"tags_count":189,"template":false,"template_full_name":null,"purl":"pkg:github/sasjs/server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sasjs%2Fserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sasjs%2Fserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sasjs%2Fserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sasjs%2Fserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sasjs","download_url":"https://codeload.github.com/sasjs/server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sasjs%2Fserver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28748573,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T07:58:02.558Z","status":"ssl_error","status_checked_at":"2026-01-25T07:57:57.153Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sas","sasjs"],"created_at":"2026-01-25T08:07:17.848Z","updated_at":"2026-01-25T08:07:18.660Z","avatar_url":"https://github.com/sasjs.png","language":"TypeScript","funding_links":["https://github.com/sponsors/sasjs"],"categories":[],"sub_categories":[],"readme":"# SASjs Server\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n\n[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-)\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\nSASjs Server provides a NodeJS wrapper for calling the SAS binary executable. It can be installed on an actual SAS server, or locally on your desktop. It provides:\n\n- Virtual filesystem for storing SAS programs and other content\n- Ability to execute Stored Programs from a URL\n- Ability to create web apps using simple Desktop SAS\n- REST API with Swagger Docs\n\nOne major benefit of using SASjs Server alongside other components of the SASjs framework such as the [CLI](https://cli.sasjs.io), [Adapter](https://adapter.sasjs.io) and [Core](https://core.sasjs.io) library, is that the projects you create can be very easily ported to SAS 9 (Stored Process server) or Viya (Job Execution server).\n\nSASjs Server is available in two modes - Desktop (without authentication) and Server (with authentication, and a database)\n\n## Installation\n\nInstallation can be made programmatically using command line, or by manually downloading and running the executable.\n\n### Programmatic\n\nFetch the relevant package from github using `curl`, eg as follows (for linux):\n\n```bash\ncurl -L https://github.com/sasjs/server/releases/latest/download/linux.zip \u003e linux.zip\nunzip linux.zip\n```\n\nThe app can then be launched with `./api-linux` and prompts followed (if ENV vars not set).\n\n### Manual\n\n1. Download the relevant package from the [releases](https://github.com/sasjs/server/releases) page\n2. Trigger by double clicking (windows) or executing from commandline.\n\nYou are presented with two prompts (if not set as ENV vars):\n\n- Location of your `sas.exe` / `sas.sh` executable\n- Path to a filesystem location for Stored Programs and temporary files\n\n## ENV Var configuration\n\nWhen launching the app, it will make use of specific environment variables. These can be set in the following places:\n\n- Configured globally in `/etc/environment` file\n- Export in terminal or shell script (`export VAR=VALUE`)\n- Prepended in the command\n- Enter in the `.env` file alongside the executable\n\nExample contents of a `.env` file:\n\n```\n#\n## Core Settings\n#\n\n\n# MODE options: [desktop|server] default: `desktop`\n# Desktop mode is single user and designed for workstation use\n# Server mode is multi-user and suitable for intranet / internet use\nMODE=\n\n# A comma separated string that defines the available runTimes.\n# Priority is given to the runtime that comes first in the string.\n# Possible options at the moment are sas, js, py and r\n\n# This string sets the priority of the available analytic runtimes\n# Valid runtimes are SAS (sas), JavaScript (js), Python (py) and R (r)\n# For each option provided, there should be a corresponding path,\n# eg SAS_PATH, NODE_PATH, PYTHON_PATH or RSCRIPT_PATH\n# Priority is given to runtimes earlier in the string\n# Example options:  [sas,js,py | js,py | sas | sas,js | r | sas,r]\nRUN_TIMES=\n\n# Path to SAS executable (sas.exe / sas.sh)\nSAS_PATH=/path/to/sas/executable.exe\n\n# Path to Node.js executable\nNODE_PATH=~/.nvm/versions/node/v16.14.0/bin/node\n\n# Path to Python executable\nPYTHON_PATH=/usr/bin/python\n\n# Path to R executable\nR_PATH=/usr/bin/Rscript\n\n# Path to working directory\n# This location is for SAS WORK, staged files, DRIVE, configuration etc\nSASJS_ROOT=./sasjs_root\n\n\n# This location is for files, sasjs packages and appStreamConfig.json\nDRIVE_LOCATION=./sasjs_root/drive\n\n\n# options: [http|https] default: http\nPROTOCOL=\n\n# default: 5000\nPORT=\n\n# options: [sas9|sasviya]\n# If not present, mocking function is disabled\nMOCK_SERVERTYPE=\n\n# default: /api/mocks\n# Path to mocking folder, for generic responses, it's sub directories should be: sas9, viya, sasjs\n# Server will automatically use subdirectory accordingly\nSTATIC_MOCK_LOCATION=\n\n#\n## Additional SAS Options\n#\n\n\n# On windows use SAS_OPTIONS and on unix use SASV9_OPTIONS\n# Any options set here are automatically applied in the SAS session\n# See: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/hostunx/p0wrdmqp8k0oyyn1xbx3bp3qy2wl.htm\n# And: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/hostwin/p0drw76qo0gig2n1kcoliekh605k.htm#p09y7hx0grw1gin1giuvrjyx61m6\nSAS_OPTIONS= -NOXCMD\nSASV9_OPTIONS= -NOXCMD\n\n\n#\n## Additional Web Server Options\n#\n\n# ENV variables for PROTOCOL: `https`\nPRIVATE_KEY=privkey.pem (required)\nCERT_CHAIN=certificate.pem (required)\nCA_ROOT=fullchain.pem (optional)\n\n## ENV variables required for MODE: `server`\nDB_CONNECT=mongodb+srv://\u003cDB_USERNAME\u003e:\u003cDB_PASSWORD\u003e@\u003cCLUSTER\u003e/\u003cDB_NAME\u003e?retryWrites=true\u0026w=majority\n\n# options: [mongodb|cosmos_mongodb] default: mongodb\nDB_TYPE=\n\n# AUTH_PROVIDERS options: [ldap] default: ``\nAUTH_PROVIDERS=\n\n## ENV variables required for AUTH_MECHANISM: `ldap`\nLDAP_URL= \u003cLDAP_SERVER_URL\u003e\nLDAP_BIND_DN= \u003ccn=admin,ou=system,dc=cloudron\u003e\nLDAP_BIND_PASSWORD = \u003cpassword\u003e\nLDAP_USERS_BASE_DN = \u003cou=users,dc=cloudron\u003e\nLDAP_GROUPS_BASE_DN = \u003cou=groups,dc=cloudron\u003e\n\n# options: [disable|enable] default: `disable` for `server` \u0026 `enable` for `desktop`\n# If enabled, be sure to also configure the WHITELIST of third party servers.\nCORS=\n\n# options: \u003chttp://localhost:3000 https://abc.com ...\u003e space separated urls\nWHITELIST=\n\n# HELMET Cross Origin Embedder Policy\n# Sets the Cross-Origin-Embedder-Policy header to require-corp when `true`\n# options: [true|false] default: true\n# Docs: https://helmetjs.github.io/#reference (`crossOriginEmbedderPolicy`)\nHELMET_COEP=\n\n# HELMET Content Security Policy\n# Path to a json file containing HELMET `contentSecurityPolicy` directives\n# Docs: https://helmetjs.github.io/#reference\n#\n# Example config:\n# {\n#   \"img-src\": [\"'self'\", \"data:\"],\n#   \"script-src\": [\"'self'\", \"'unsafe-inline'\"],\n#   \"script-src-attr\": [\"'self'\", \"'unsafe-inline'\"]\n# }\nHELMET_CSP_CONFIG_PATH=./csp.config.json\n\n# To prevent brute force attack on login route we have implemented rate limiter\n# Only valid for MODE: server\n# Following are configurable env variable rate limiter\n\n# After this, access is blocked for 1 day\nMAX_WRONG_ATTEMPTS_BY_IP_PER_DAY = \u003cnumber\u003e default: 100;\n\n\n# After this, access is blocked for an hour\n# Store number for 24 days since first fail\n# Once a successful login is attempted, it resets\nMAX_CONSECUTIVE_FAILS_BY_USERNAME_AND_IP = \u003cnumber\u003e default: 10;\n\n# Name of the admin user that will be created on startup if not exists already\n# Default is `secretuser`\nADMIN_USERNAME=secretuser\n\n# Temporary password for the ADMIN_USERNAME, which is in place until the first login\n# Default is `secretpassword`\nADMIN_PASSWORD_INITIAL=secretpassword\n\n# Specify whether app has to reset the ADMIN_USERNAME's password or not\n# Default is NO. Possible options are YES and NO\n# If ADMIN_PASSWORD_RESET is YES then the ADMIN_USERNAME will be prompted to change the password from ADMIN_PASSWORD_INITIAL on their next login. This will repeat on every server restart, unless the option is removed / set to NO.\nADMIN_PASSWORD_RESET=NO\n\n# LOG_FORMAT_MORGAN options: [combined|common|dev|short|tiny] default: `common`\n# Docs: https://www.npmjs.com/package/morgan#predefined-formats\nLOG_FORMAT_MORGAN=\n\n# This location is for server logs with classical UNIX logrotate behavior\nLOG_LOCATION=./sasjs_root/logs\n\n```\n\n## Persisting the Session\n\nNormally the server process will stop when your terminal dies. To keep it going you can use the following suggested approaches:\n\n1. Linux Background Job\n2. NPM package `pm2`\n\n### Background Job\n\nTrigger the command using NOHUP, redirecting the output commands, eg `nohup ./api-linux \u003e server.log 2\u003e\u00261 \u0026`.\n\nYou can now see the job running using the `jobs` command. To ensure that it will still run when your terminal is closed, execute the `disown` command. To kill it later, use the `kill -9 \u003cpid\u003e` command. You can see your sessions using `top -u \u003cuserid\u003e`. Type `c` to see the commands being run against each pid.\n\n### PM2\n\nInstall the npm package [pm2](https://www.npmjs.com/package/pm2) (`npm install pm2@latest -g`) and execute, eg as follows:\n\n```bash\nexport SAS_PATH=/opt/sas9/SASHome/SASFoundation/9.4/sasexe/sas\nexport PORT=5001\nexport SASJS_ROOT=./sasjs_root\n\npm2 start api-linux\n```\n\nTo get the logs (and some useful commands):\n\n```bash\npm2 [list|ls|status]\npm2 logs\npm2 logs --lines 200\n```\n\nManaging processes:\n\n```\npm2 restart app_name\npm2 reload app_name\npm2 stop app_name\npm2 delete app_name\n```\n\nInstead of `app_name` you can pass:\n\n- `all` to act on all processes\n- `id` to act on a specific process id\n\n## Server Version\n\nThe following credentials can be used for the initial connection to SASjs/server. It is highly recommended to change these on first use.\n\n- CLIENTID: `clientID1`\n- USERNAME: `secretuser`\n- PASSWORD: `secretpassword`\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/saadjutt01\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/8914650?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSaad Jutt\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sasjs/server/commits?author=saadjutt01\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/sasjs/server/commits?author=saadjutt01\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/sabhas\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/82647447?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSabir Hassan\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sasjs/server/commits?author=sabhas\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/sasjs/server/commits?author=sabhas\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://www.erudicat.com/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/25773492?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eYury Shkoda\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sasjs/server/commits?author=YuryShkoda\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/sasjs/server/commits?author=YuryShkoda\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/medjedovicm\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/18329105?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMihajlo Medjedovic\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sasjs/server/commits?author=medjedovicm\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/sasjs/server/commits?author=medjedovicm\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://4gl.io/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/4420615?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAllan Bowe\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sasjs/server/commits?author=allanbowe\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/sasjs/server/commits?author=allanbowe\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/VladislavParhomchik\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/83717836?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eVladislav Parhomchik\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sasjs/server/commits?author=VladislavParhomchik\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/kknapen\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/78609432?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKoen Knapen\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#userTesting-kknapen\" title=\"User Testing\"\u003e📓\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsasjs%2Fserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsasjs%2Fserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsasjs%2Fserver/lists"}