{"id":22712245,"url":"https://github.com/buildit/bookit-server","last_synced_at":"2025-03-29T22:21:53.452Z","repository":{"id":78235651,"uuid":"86631439","full_name":"buildit/bookit-server","owner":"buildit","description":null,"archived":false,"fork":false,"pushed_at":"2017-10-26T14:24:09.000Z","size":1561,"stargazers_count":1,"open_issues_count":2,"forks_count":2,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-02-04T23:32:02.604Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/buildit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2017-03-29T21:33:19.000Z","updated_at":"2017-06-23T18:37:25.000Z","dependencies_parsed_at":"2023-04-13T22:51:07.314Z","dependency_job_id":null,"html_url":"https://github.com/buildit/bookit-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildit%2Fbookit-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildit%2Fbookit-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildit%2Fbookit-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buildit%2Fbookit-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/buildit","download_url":"https://codeload.github.com/buildit/bookit-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246250089,"owners_count":20747293,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-12-10T13:09:47.429Z","updated_at":"2025-03-29T22:21:53.445Z","avatar_url":"https://github.com/buildit.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bookit server\n\nA server for [Bookit](https://github.com/buildit/bookit-web).\n\n## Quick start\nAfter checkout, this will get you started.\n\nFirst, make sure the environment configuration is set up correctly. Find the file named `.env-sample`. Copy it and name the new file `.env`. This gives you the minimum environment configuration you need in order to run the app in dev mode.\n\nThen run:\n```\nnpm install\nnpm run build\nnpm run server\n```\n\nAlternatively, to watch for changes when developing, do the following:\n\nIn one terminal:\n```\nnpm run watch\n```\n\nAnd in another:\n```\nnpm run server\n```\n\nTo watch unit tests while developing, open yet another terminal and run:\n```\nnpm run watch:unit\n```\n\nYou can check these endpoints, just to make sure everything's working:\n - Room list: `http://localhost:8888/rooms/nyc`\n - Meeting list: `http://localhost:8888/rooms/nyc/meetings?start=2017-03-08\u0026end=2017-03-12`\n\n## Microsoft Azure Setup\n\n[Setting up Microsoft services for Bookit](./docs/setting-up-azure.md)\n\n## Modes of operation\n\nThe back end is heavily geared towards testing and stand-alone operation at the moment.  It has a dev mode against an\nin-memory generated meeting list, a dev mode against a test Azure AD using the Microsoft Graph API, a unit-test\nconfiguration, and an integration test configuration.  The **default mode of operation is in-memory dev**.  When the\napp runs in \"in-mem\" mode, an `EventGenerator` creates a bunch of sample event data. The events are randomized, so\nyou will see somewhat different results with every run.\n\n\n### Accessing additional modes\n\nTo work with additional modes, you will need to create a plaintext file named '.env' in the root of your checkout \ndefining the following variables.  \n\n##### Toggle usage of the Graph API backend\n```\nUSE_AZURE=true\n```\n\n##### MICROSOFT GRAPH SETTINGS\nThese settings represent the identity that the application will use to access MS Graph API services.\n\nThe variable that is used for selecting the identity is called `CLOUD_CONFIG`.  For now, use 'buildit' as the value.\n```\nCLOUD_CONFIG=buildit\n```\n\nThere is a secret for each identity that is named `\u003cIDENTITY\u003e_SECRET`.  Once again, for now, use `BUILDIT_SECRET`. Please\n obtain these and other secrets by following the AWS Parameter Store steps below.\n```\nBUILDIT_SECRET=secret-obtained-from-aws (see below)\n```\n\n## Azure administration\n\nIf you need to access the administration user and password details for a particular identity, you can get that from AWS as well.  \nThe parameter names to pull would be `\u003cIDENTITY\u003e_ADMIN_NAME` and `\u003cIDENTITY\u003e_ADMIN_PASSWORD`.  Follow the directions below on\nhow to get AWS secrets.\n\n\n## Obtaining Secrets from AWS Parameter Store\n\nWe store secrets for the system in AWS' SSM Parameter Store.  It does all the hard work of encrypting our application \nparameters.\n\n\"Global\" parameters are stored under the `/bookit` namespace.  So global parameter `BAR` is stored at `/bookit/BAR`  \nEnvironment-specific parameters are stored in the `/bookit/\u003cenvironment\u003e` namespace.  So if the environment is \n`foo`, parameter `BAZ` is stored at `/bookit/foo/BAZ`.\n\n### Get access to AWS\nSpeak to a fellow developer to obtain AWS keys, which are comprised of a key id and key secret.  After that run:\n\n```\naws configure\n```\n(_Note:_ Use us-east-1 as your region, when asked, for now.  Note that this can be overridden on the command-line as shown below.)\n\nAfter this, you should be good to go to run the AWS CLI to pull in environment secrets:\n\n```\n$ aws ssm get-parameters --region us-east-1 --name /bookit/\u003cenvironment\u003e/BUILDIT_SECRET --with-decryption\n\u003c\u003cThe secret is printed here\u003e\u003e\n```\n(_Note:_ You can leave out the region parameter if you provided one at configuration time.  The above demonstrates the inclusion\nof the region parameter for demonstration purposes).\n\n### Login credentials for sample users\n\nWe have two sample users that we can use while developing. Their credentials are stored in the AWS Parameter Store. You can get these credentials with the following:\n\n```\n# Admin user\naws ssm get-parameters --region us-east-1 --name /bookit/BUILDIT_ADMIN_NAME /bookit/BUILDIT_ADMIN_PASSWORD --with-decryption \n\n# Regular user\naws ssm get-parameters --region us-east-1 --name /bookit/BUILDIT_REGULAR_USER_NAME /bookit/BUILDIT_REGULAR_USER_PASSWORD --with-decryption \n```\n\n\n## Authentication\nThere are a few endpoints that require a token in order to access.  It's either because it needs\nto be protected or because it is user-context sensitive.  The server has an endpoint for retrieving a token for using\nin some subsequent requests.  Send a json object that conforms to the below interface.\n\n```\nPOST /authenticate\n\nexport interface Credentials {\n  user: string;\n  password: string;\n}\n```\nYou will get back an object that has a member called 'token.'  The token is hardcoded to last 60 minutes at the moment.\n\n```\nexport interface TokenInfo {\n  user: string;\n  password: string;\n  iat: number;\n  exp: number;\n}\n```\n\nThis token should be placed in the header for authentication for those endpoints that require it.\n````\nreturn request(app).get('/backdoor')\n                  .set('x-access-token', token)\n                  .expect(200)\n````\n\n## Code architecture\nThe environment bootstrapping is simple and is mainly driven off the two environment variables above.  This can be\nfound under src/config.  The environment loading code is in env.ts.  The config is loaded using\n [node-config](https://github.com/lorenwest/node-config).\n\nThe run-time configuration is generated in src/config/runtime.  The creation of all services is\ndone in configuration.ts.  There are interfaces for each service and mainly two implementations.\nOne is Mock and the other is MSGraph.\n\n## Services\nThere are a small set of services under which the code is organized under src/services.  \n\n##### Mock\nA version that implements the interface and has basic or pass-through functionality.  Sometimes these implementations imitate Microsoft's idiosyncracies like the PassthroughMeetingService in CachedMeetingService.\n\n##### MS Graph\nThese are the services that connect to Microsoft.\n\n##### Cached\nWraps the service and caches data from the underlying service.  This is typically used with the cloud connected\nservices.  However, for testing purposes, there is a use case where a cached service functions as\nthe actual service and delegates to a pass-through service.\n\n\n#### TokenOperations\nThis is a class the provides two types of tokens.  The first are JWT tokens for protected endpoints.  The second\nare cloud tokens for MS Graph calls.\n\n#### RoomService\nThis service provides room lists for a particular location (e.g. for NYC or Copenhagen).\n\nOur data store, Microsoft Azure AD, has no notion of a \"room\" or a \"room list\", so we decided to store the room list as a \"Group\" in Microsoft Azure. When setting up a new location, the Bookit administrator works with the Azure AD administrator to create a new group, populated with a list of rooms for that location.\n\n#### UserService\nThis service provides a user list.\n\n#### MeetingService\nThis service is the main service of the application that does CRUD meeting operations.\n\n## REST\nThe app is using express for its web server.  There are three endpoint categories:\n\n##### Test\nFor test routes to see if the server is up.\n\n##### Authentication\nTo set up the login routes\n\n##### Meetings\nThe routes for CRUD meeting operations that bookit-web interacts with.\n\n## Special cases\nMeetingOps seems to be an IOC class meant for reusing logic (e.g. checking for meeting availability) against an\ninterchangeable set of services.  This class is actively being gutted as it's not maintainting any state nor representing\nan interface of much value.\n\n## Useful links\n\n[Office Portal](https://portal.office.com/) (resource management)\n\n[Azure Portal](https://portal.azure.com) (application management)\n\n[Node.js Graph API](https://github.com/microsoftgraph/msgraph-sdk-javascript)\n\n[Calendar REST API reference](https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/calendar)  \n\n[Microsoft Graph API permissins list](https://developer.microsoft.com/en-us/graph/docs/authorization/permission_scopes)\n\n## Docker packaging\n\nThe Travis build pushes to Amazon's EC2 Container Registry (ECR) only for the `master` branch.\nWe do not perform separate `npm i` and reuse build `node_modules` with `npm prune --production`.\n\n## Local Docker, Server Only\nLocal build and run example:\n\n`docker build . -t bookit-server:local \u0026\u0026 USE_CLOUD=true CLOUD_CONFIG=buildit BUILDIT_SECRET=\u003csecret from above\u003e docker run --rm -ti -p 8888:8888  bookit-server:local`\n\n\n## Local Docker, both Server \u0026 Web (Experimental)\nThis is close, but needs a bit more work.  It's sensitive to the Azure AD setup du jour.\n```\n$(aws ecr get-login)\ndocker-compose up\n```\n(if the basic ECR login above doesn't work, try `$(aws ecr get-login | sed 's/-e none//')`)\n\n## CI/CD\nOn commits to `master`, if all unit tests pass, Travis creates a new Docker image and pushes it to an AWS ECR repo. \nAfter a successful push to ECR, the app is deployed to the integration environment. Then Integration tests are \nrun. Only if the integration tests run successfully, does Travis then deploy the app to the staging environment.\n\nNote that this process is currently a little odd.  The \"integration tests\" are tests that assume availability of the \nOffice365/GraphApi services.  There currently are no API-level tests of the deployed bookit-server itself.  Thus,\nhaving passed integration tests does not truly imply that the deployed code has been tested in the integration\nenvironment.  Nonetheless, if the integration tests pass, the code is deployed into the staging environment.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuildit%2Fbookit-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuildit%2Fbookit-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuildit%2Fbookit-server/lists"}