From 755f5e48b48f9b77c7c01b7a5314bc5d8836c327 Mon Sep 17 00:00:00 2001 From: William Belle Date: Fri, 18 Aug 2023 13:28:20 +0200 Subject: [PATCH 1/7] Fix environment variables for Docker Compose (#98) --- docker-compose.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index d034cc2..5bfebba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,18 @@ services: image: search-api container_name: search-api environment: + - SEARCH_API_ENABLE_CSE=${SEARCH_API_ENABLE_CSE} + - SEARCH_API_ENABLE_LDAP=${SEARCH_API_ENABLE_LDAP} + - SEARCH_API_ENABLE_UNIT=${SEARCH_API_ENABLE_UNIT} + - SEARCH_API_ENABLE_GRAPHSEARCH=${SEARCH_API_ENABLE_GRAPHSEARCH} - SEARCH_API_CSE_API_KEY=${SEARCH_API_CSE_API_KEY} - SEARCH_API_CSE_CX=${SEARCH_API_CSE_CX} + - SEARCH_API_CADIDB_HOST=${SEARCH_API_CADIDB_HOST} + - SEARCH_API_CADIDB_PORT=${SEARCH_API_CADIDB_PORT} + - SEARCH_API_CADIDB_DATABASE=${SEARCH_API_CADIDB_DATABASE} + - SEARCH_API_CADIDB_USER=${SEARCH_API_CADIDB_USER} + - SEARCH_API_CADIDB_PASSWORD=${SEARCH_API_CADIDB_PASSWORD} + - SEARCH_API_LDAP_URL=${SEARCH_API_LDAP_URL} + - SEARCH_API_LDAP_ROOTS_FILTER=${SEARCH_API_LDAP_ROOTS_FILTER} ports: - '5555:5555' From 970aeac6738bae1869f40ece875d212d8012e491 Mon Sep 17 00:00:00 2001 From: William Belle Date: Fri, 18 Aug 2023 13:37:46 +0200 Subject: [PATCH 2/7] Fix 'node' engine requirement (#99) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 03e47bc..6766ead 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "supertest": "^6.3.3" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^16.10.0 || >=18.0.0" } }, "node_modules/@ampproject/remapping": { diff --git a/package.json b/package.json index 1ed4780..c9ca24b 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "author": "William Belle ", "homepage": "https://github.com/epfl-si/search-api#readme", "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^16.10.0 || >=18.0.0" }, "scripts": { "docs": "jsdoc -c jsdoc.json", From 5c24977ce2b2adee870e2b8fb88904bb4c8388f6 Mon Sep 17 00:00:00 2001 From: William Belle Date: Fri, 25 Aug 2023 17:05:32 +0200 Subject: [PATCH 3/7] Improve section deploy in documentation (Ansible) (#101) --- CONTRIBUTING.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14453a1..47376eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,8 +57,21 @@ git push origin main --tags ## Deploy -Log into `ghcr.io` and `os-docker-registry.epfl.ch`, then - -```bash -./ansible/searchapisible [--prod] +Log into `ghcr.io`, `os-docker-registry.epfl.ch` and OpenShift, then + +```text +Usage: ./ansible/searchapisible [options] + +Options: + -h, --help Show help message and exit + --list-tags List all available tags + --prod Deploy in production + -t, --tags Run tasks tagged with these values [string] + -v, --verbose Causes Ansible to print more debug messages + --version Show version number + +Examples: + ./ansible/searchapisible + ./ansible/searchapisible --prod + ./ansible/searchapisible --prod -t app.restart ``` From fec22b9166bba3bbbe7cb23a0a307e006f3145c1 Mon Sep 17 00:00:00 2001 From: William Belle Date: Mon, 28 Aug 2023 11:00:04 +0200 Subject: [PATCH 4/7] Improve Docker image (speed and permissions) (#102) --- docker/Dockerfile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 2438dcd..838ef5e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -7,16 +7,17 @@ RUN \ ENV TZ="Europe/Zurich" \ NODE_ENV="production" -WORKDIR /app +USER node +WORKDIR /usr/src/app -COPY package*.json ./ -COPY src /app +COPY --chown=node:node package*.json ./ RUN \ npm ci --omit=dev && \ npm cache clean --force +COPY --chown=node:node src ./ + EXPOSE 5555 -USER node -CMD [ "dumb-init", "node", "/app/server.js" ] +CMD [ "dumb-init", "node", "/usr/src/app/server.js" ] From b92af0b25dc470e9e46f1b5c7e2e8ec3648924d3 Mon Sep 17 00:00:00 2001 From: William Belle Date: Tue, 29 Aug 2023 09:48:50 +0200 Subject: [PATCH 5/7] Handle ldap client errors (#103) --- package.json | 4 ++-- src/services/ldap.service.js | 14 +++++++---- tests/ldap.test.js | 46 +++++++++++++++++++++++++++++------- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index c9ca24b..7322e12 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "prettier": "prettier --check --ignore-unknown '**' '!**/*.js' '!**/ansible-deps-cache'", "prettier:fix": "prettier --write --ignore-unknown '**' '!**/*.js' '!**/ansible-deps-cache'", "start": "nodemon src/server.js", - "test": "npm run lint && jest --forceExit --verbose", - "test:coverage": "jest --coverage --forceExit --verbose", + "test": "npm run lint && jest --verbose", + "test:coverage": "jest --coverage --verbose", "test:watch": "jest --watchAll --verbose" }, "devDependencies": { diff --git a/src/services/ldap.service.js b/src/services/ldap.service.js index f398a2e..009bd65 100644 --- a/src/services/ldap.service.js +++ b/src/services/ldap.service.js @@ -1,9 +1,6 @@ const ldap = require('ldapjs'); const ldapConfig = require('../configs/ldap.config'); -// http://ldapjs.org/client.html -const client = ldap.createClient(ldapConfig.client); - function getSciper (entry) { const uids = entry.attributes.filter( f => f.type === 'uniqueIdentifier' @@ -13,6 +10,12 @@ function getSciper (entry) { function searchAll (base, options) { return new Promise((resolve, reject) => { + // http://ldapjs.org/client.html + const client = ldap.createClient(ldapConfig.client); + client.on('error', (err) => { + reject(err); + }); + client.search(base, options, (x, res) => { const personsBySciper = {}; @@ -25,16 +28,17 @@ function searchAll (base, options) { }); res.on('timeout', (err) => { - console.error('[error] ' + err.message); + client.destroy(); reject(err); }); res.on('error', (err) => { - console.error('[error] ' + err.message); + client.destroy(); reject(err); }); res.on('end', () => { + client.destroy(); resolve(personsBySciper); }); }); diff --git a/tests/ldap.test.js b/tests/ldap.test.js index a64b140..fc7c74b 100644 --- a/tests/ldap.test.js +++ b/tests/ldap.test.js @@ -10,15 +10,6 @@ describe('Test LDAP Service', () => { (client, dn, opts, searchCallbackFn) => searchCallbackFn() ); - jest.spyOn(ldap, 'createClient').mockReturnValue({ - url: { - host: process.env.SEARCH_API_LDAP_URL, - timeout: 50, - connectTimeout: 30 - }, - search: mockSearchFn - }); - beforeEach(() => { jest.clearAllMocks(); console.error = testConsoleError; @@ -29,12 +20,38 @@ describe('Test LDAP Service', () => { console.error = originalConsoleError; }); + test('It should return an error with a wrong ldap url', async () => { + const ldapConfig = require('../src/configs/ldap.config'); + ldapConfig.client.url = 'ldaps://0.0.0.0:666'; + ldapConfig.client.connectTimeout = 50; + + const ldapService = require('../src/services/ldap.service'); + expect.assertions(2); + try { + await ldapService.searchAll(); + } catch (error) { + expect(error.code).toEqual('ERR_ASSERTION'); + expect(error.message).toEqual('search base'); + } + }); + test('It should return an error on bad search request', async () => { const emitter = new EventEmitter(); mockSearchFn.mockImplementationOnce( (dn, opts, searchCallbackFn) => searchCallbackFn(false, emitter) ); + jest.spyOn(ldap, 'createClient').mockReturnValue({ + url: { + host: process.env.SEARCH_API_LDAP_URL, + timeout: 50, + connectTimeout: 30 + }, + destroy: jest.fn(), + on: jest.fn(), + search: mockSearchFn + }); + setTimeout(() => { emitter.emit('error', new Error('Bad search request')); }, 40); @@ -56,6 +73,17 @@ describe('Test LDAP Service', () => { (dn, opts, searchCallbackFn) => searchCallbackFn(false, emitter) ); + jest.spyOn(ldap, 'createClient').mockReturnValue({ + url: { + host: process.env.SEARCH_API_LDAP_URL, + timeout: 50, + connectTimeout: 30 + }, + destroy: jest.fn(), + on: jest.fn(), + search: mockSearchFn + }); + setTimeout(() => { emitter.emit('timeout', new Error('Timeout search request')); }, 40); From 4535705d15029be8daa114c7c9374c4427bc0bc1 Mon Sep 17 00:00:00 2001 From: Azecko <30987143+Azecko@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:56:31 +0200 Subject: [PATCH 6/7] Address route (#100) * `/api/address/` route It is basically a route that works like `/api/ldap/`. But it returns the address of the person. `fullAddress`, `postalCode`, `postOfficeBox` --- .jest/setEnvVars.js | 1 + Makefile | 1 + README.md | 17 ++++++ ansible/roles/search-api-k8s/tasks/app.yml | 2 + docker-compose.yml | 1 + src/app.js | 6 ++ src/configs/api.config.js | 1 + src/controllers/address.controller.js | 31 ++++++++++ src/routes/address.route.js | 8 +++ src/utils/ldap.util.js | 52 ++++++++++++++++- tests/address.test.js | 58 +++++++++++++++++++ tests/app.test.js | 1 + .../resources/address/json-sciper-670001.json | 21 +++++++ tests/resources/ldap/directory.json | 35 ++++++++--- 14 files changed, 227 insertions(+), 8 deletions(-) create mode 100644 src/controllers/address.controller.js create mode 100644 src/routes/address.route.js create mode 100644 tests/address.test.js create mode 100644 tests/resources/address/json-sciper-670001.json diff --git a/.jest/setEnvVars.js b/.jest/setEnvVars.js index c045282..5a8c3db 100644 --- a/.jest/setEnvVars.js +++ b/.jest/setEnvVars.js @@ -1,5 +1,6 @@ process.env.SEARCH_API_ENABLE_CSE='True' process.env.SEARCH_API_ENABLE_LDAP='True' +process.env.SEARCH_API_ENABLE_ADDRESS='True' process.env.SEARCH_API_ENABLE_UNIT='True' process.env.SEARCH_API_ENABLE_GRAPHSEARCH='True' diff --git a/Makefile b/Makefile index 2319bce..bc9dbd7 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ endif print-env: check-env @echo "SEARCH_API_ENABLE_CSE=${SEARCH_API_ENABLE_CSE}" @echo "SEARCH_API_ENABLE_LDAP=${SEARCH_API_ENABLE_LDAP}" + @echo "SEARCH_API_ENABLE_ADDRESS=${SEARCH_API_ENABLE_ADDRESS}" @echo "SEARCH_API_ENABLE_UNIT=${SEARCH_API_ENABLE_UNIT}" @echo "SEARCH_API_ENABLE_GRAPHSEARCH=${SEARCH_API_ENABLE_GRAPHSEARCH}" @echo "" diff --git a/README.md b/README.md index c30ba62..9b72f0a 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,22 @@ - [/api/ldap?q=278890][ldap-1] - [/api/ldap?q=nicolas.borboen@epfl.ch&hl=en][ldap-2] +## Address + +### Endpoint + +`GET /api/address` + +### Parameters + +| Name | Type | Comments | +| ---- | -------- | -------------- | +| `q` | `String` | Query (sciper) | + +### Examples + +- [/api/address?q=278890][address-1] + ## Unit ### Endpoint @@ -108,3 +124,4 @@ See [Contributing](CONTRIBUTING.md). [unit-3]: http://127.0.0.1:5555/api/unit?acro=vpo [graphsearch-1]: http://127.0.0.1:5555/api/graphsearch?q=math [graphsearch-2]: http://127.0.0.1:5555/api/graphsearch?q=vetterli +[address-1]: http://127.0.0.1:5555/api/address?q=278890 diff --git a/ansible/roles/search-api-k8s/tasks/app.yml b/ansible/roles/search-api-k8s/tasks/app.yml index f2ada74..de9737b 100644 --- a/ansible/roles/search-api-k8s/tasks/app.yml +++ b/ansible/roles/search-api-k8s/tasks/app.yml @@ -26,6 +26,8 @@ value: '{{ searchapi_secrets.SEARCH_API_ENABLE_CSE |string }}' - name: SEARCH_API_ENABLE_LDAP value: '{{ searchapi_secrets.SEARCH_API_ENABLE_LDAP |string }}' + - name: SEARCH_API_ENABLE_ADDRESS + value: '{{ searchapi_secrets.SEARCH_API_ENABLE_ADDRESS |string }}' - name: SEARCH_API_ENABLE_UNIT value: '{{ searchapi_secrets.SEARCH_API_ENABLE_UNIT |string }}' - name: SEARCH_API_ENABLE_GRAPHSEARCH diff --git a/docker-compose.yml b/docker-compose.yml index 5bfebba..cd20ab8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: environment: - SEARCH_API_ENABLE_CSE=${SEARCH_API_ENABLE_CSE} - SEARCH_API_ENABLE_LDAP=${SEARCH_API_ENABLE_LDAP} + - SEARCH_API_ENABLE_ADDRESS=${SEARCH_API_ENABLE_ADDRESS} - SEARCH_API_ENABLE_UNIT=${SEARCH_API_ENABLE_UNIT} - SEARCH_API_ENABLE_GRAPHSEARCH=${SEARCH_API_ENABLE_GRAPHSEARCH} - SEARCH_API_CSE_API_KEY=${SEARCH_API_CSE_API_KEY} diff --git a/src/app.js b/src/app.js index 578ca7e..e2a1507 100644 --- a/src/app.js +++ b/src/app.js @@ -10,6 +10,7 @@ const cseRouter = require('./routes/cse.route'); const peopleRouter = require('./routes/people.route'); const unitRouter = require('./routes/unit.route'); const semanticRouter = require('./routes/semantic.route'); +const addressRouter = require('./routes/address.route'); const app = express(); @@ -39,6 +40,11 @@ if (configApi.enableLdap) { app.use('/api/ldap', peopleRouter); } +// Address +if (configApi.enableAddress) { + app.use('/api/address', addressRouter); +} + // Unit if (configApi.enableUnit) { app.use('/api/unit', unitRouter); diff --git a/src/configs/api.config.js b/src/configs/api.config.js index fd3b445..fb00d3f 100644 --- a/src/configs/api.config.js +++ b/src/configs/api.config.js @@ -3,6 +3,7 @@ const helper = require('../utils/helper.util'); const api = { enableCse: helper.setBool('SEARCH_API_ENABLE_CSE'), enableLdap: helper.setBool('SEARCH_API_ENABLE_LDAP'), + enableAddress: helper.setBool('SEARCH_API_ENABLE_ADDRESS'), enableUnit: helper.setBool('SEARCH_API_ENABLE_UNIT'), enableGraphsearch: helper.setBool('SEARCH_API_ENABLE_GRAPHSEARCH') }; diff --git a/src/controllers/address.controller.js b/src/controllers/address.controller.js new file mode 100644 index 0000000..e3fdde7 --- /dev/null +++ b/src/controllers/address.controller.js @@ -0,0 +1,31 @@ +const ldapUtil = require('../utils/ldap.util'); +const addressService = require('../services/people.service'); +const appCache = require('../services/cache.service'); + +async function get (req, res) { + const q = req.query.q || ''; + if (!/^[0-9]{6}$/.test(q)) { + return res.json({}); + } + + if (appCache.has(req.originalUrl)) { + return res.send(appCache.get(req.originalUrl)); + } else { + try { + const ldapResults = await addressService.getPersonBySciper(q); + const jsonResponse = ldapUtil.ldapAddress2api(ldapResults); + appCache.set(req.originalUrl, jsonResponse); + return res.json(jsonResponse); + } catch (err) { + console.error('[error] ', err.message); + return res.status(400).json({ + success: false, + error: 'Oops, something went wrong' + }); + } + } +} + +module.exports = { + get +}; diff --git a/src/routes/address.route.js b/src/routes/address.route.js new file mode 100644 index 0000000..5ba1ab2 --- /dev/null +++ b/src/routes/address.route.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); + +const addressController = require('../controllers/address.controller'); + +router.get('/', addressController.get); + +module.exports = router; diff --git a/src/utils/ldap.util.js b/src/utils/ldap.util.js index 8c3f82b..5b48f5d 100644 --- a/src/utils/ldap.util.js +++ b/src/utils/ldap.util.js @@ -26,6 +26,16 @@ function newLdapAccredMapper (lang) { return ldapAccredMapper; } +function newLdapAddressMapper () { + const ldapAddressMapper = { + roomNumber: ['officeList', (val) => val], + postalAddress: ['fullAddress', (val) => val[0]], + postalCode: ['postalCode', (val) => val[0]], + postOfficeBox: ['postOfficeBox', (val) => val[0]] + }; + return ldapAddressMapper; +} + function sortAccreds (obj) { return obj.sort((a, b) => a.rank - b.rank); } @@ -200,10 +210,50 @@ function ldap2api (ldapResults, q, hl) { return sortPersons(list, q); } +/** + * Convert LDAP Address search result into API result. + * + * @example + * const ldapUtil = require('../utils/ldap.util'); + * const address = ldapUtil.ldapAddress2api(ldapResults, 'Fett'); + * + * @param {object} ldapResults The result from the LDAP Address search. + * @param {string} q The query. + * @returns {object} Return the result for the API. + */ +function ldapAddress2api (ldapResults) { + const ldapAddressMapper = newLdapAddressMapper(); + const person = {}; + + for (const [sciper, entry] of Object.entries(ldapResults)) { + person.sciper = sciper; + const listAccreds = []; + for (let acc = 0; acc < entry.length; acc++) { + const accred = { + officeList: [], + path: dn2path(entry[acc].objectName), + acronym: dn2acronym(entry[acc].objectName) + }; + for (let att = 0; att < entry[acc].attributes.length; att++) { + if (entry[acc].attributes[att].type in ldapAddressMapper) { + accred[ldapAddressMapper[entry[acc].attributes[att].type][0]] = + ldapAddressMapper[ + entry[acc].attributes[att].type + ][1](entry[acc].attributes[att].values); + } + } + listAccreds.push(accred); + } + person.accreds = sortAccreds(listAccreds); + } + return person; +} + module.exports = { buildLdapQueryForPerson, dn2acronym, dn2path, getProfile, - ldap2api + ldap2api, + ldapAddress2api }; diff --git a/tests/address.test.js b/tests/address.test.js new file mode 100644 index 0000000..91ffae3 --- /dev/null +++ b/tests/address.test.js @@ -0,0 +1,58 @@ +const request = require('supertest'); + +const app = require('../src/app'); +const ldapService = require('../src/services/ldap.service'); + +describe('Test API People ("/api/address")', () => { + let testOutput = []; + const originalConsoleError = console.error; + const testConsoleError = (output) => { testOutput.push(output); }; + + beforeEach(() => { + jest.clearAllMocks(); + console.error = testConsoleError; + testOutput = []; + }); + + afterEach(() => { + console.error = originalConsoleError; + }); + + test('It should get an empty result without query', async () => { + const response = await request(app).get('/api/address'); + expect(response.statusCode).toBe(200); + expect(response.text).toMatch('{}'); + }); + + test('It should get an empty result with a small query', async () => { + const response = await request(app).get('/api/address?q=w'); + expect(response.statusCode).toBe(200); + expect(response.text).toMatch('{}'); + }); + + test('It should find sciper 670001', async () => { + const jsonResult = require('./resources/address/json-sciper-670001.json'); + const response = await request(app).get('/api/address?q=670001'); + expect(response.statusCode).toBe(200); + expect(JSON.parse(response.text)).toStrictEqual(jsonResult); + }); + + test('It should find sciper 670001 (cache)', async () => { + const jsonResult = require('./resources/address/json-sciper-670001.json'); + const response = await request(app).get('/api/address?q=670001'); + expect(response.statusCode).toBe(200); + expect(JSON.parse(response.text)).toStrictEqual(jsonResult); + }); + + test('It should not find sciper 679999 without ldap server', async () => { + const mockLdapService = jest.spyOn(ldapService, 'searchAll'); + mockLdapService.mockRejectedValue(new Error('LDAP is Gone')); + + const response = await request(app).get('/api/address?q=679999'); + expect(mockLdapService).toHaveBeenCalled(); + expect(response.statusCode).toBe(400); + expect(response.text).toMatch('Oops, something went wrong'); + expect(testOutput.length).toBe(1); + expect(testOutput[0]).toMatch('error'); + }); +}); diff --git a/tests/app.test.js b/tests/app.test.js index 540468f..7c3131a 100644 --- a/tests/app.test.js +++ b/tests/app.test.js @@ -34,6 +34,7 @@ describe('Test 404 routes', () => { testNonEnabledRoute('SEARCH_API_ENABLE_CSE', '/api/cse'); testNonEnabledRoute('SEARCH_API_ENABLE_LDAP', '/api/ldap'); + testNonEnabledRoute('SEARCH_API_ENABLE_ADDRESS', '/api/address'); testNonEnabledRoute('SEARCH_API_ENABLE_UNIT', '/api/unit'); testNonEnabledRoute('SEARCH_API_ENABLE_GRAPHSEARCH', '/api/graphsearch'); }); diff --git a/tests/resources/address/json-sciper-670001.json b/tests/resources/address/json-sciper-670001.json new file mode 100644 index 0000000..9fa8788 --- /dev/null +++ b/tests/resources/address/json-sciper-670001.json @@ -0,0 +1,21 @@ +{ + "sciper": "670001", + "accreds": [ + { + "officeList": ["Cloud City 016"], + "path": "EPFL/OT/EP-5/BESPIN", + "acronym": "BESPIN", + "fullAddress": "EPFL OT EP-5 BESPIN $ Base 016 (Bâtiment Kamino) $ Station 016 $ BO-016", + "postOfficeBox": "Station 016", + "postalCode": "BO-016" + }, + { + "officeList": ["Dune Sea 001"], + "path": "EPFL/OT/EP-6/TATOOINE", + "acronym": "TATOOINE", + "fullAddress": "EPFL OT EP-6 TATOOINE $ Base 001 (Bâtiment Tatooine) $ Station 001 $ BO-001", + "postOfficeBox": "Station 001", + "postalCode": "BO-001" + } + ] +} diff --git a/tests/resources/ldap/directory.json b/tests/resources/ldap/directory.json index 534fb5f..581758c 100644 --- a/tests/resources/ldap/directory.json +++ b/tests/resources/ldap/directory.json @@ -18,7 +18,10 @@ "Kamino", "Kamino est une planète aquatique située dans le secteur Abrion de la bordure extérieure de la galaxie." ], - "ou;lang-en": "Kamino is an aquatic planet located in the Abrion sector of the galaxy's Outer Rim." + "ou;lang-en": "Kamino is an aquatic planet located in the Abrion sector of the galaxy's Outer Rim.", + "postalCode": "JA-1468", + "postOfficeBox": "Station 1468", + "postalAddress": "EPFL PT EP-2 KAMINO $ Base 1468 (Bâtiment Kamino) $ Station 1468 $ JA-1468" } }, { @@ -40,7 +43,10 @@ "Bespin", "Bespin est une géante gazeuse du système stellaire du même nom." ], - "ou;lang-en": "Bespin is a gas giant in the star system of the same name." + "ou;lang-en": "Bespin is a gas giant in the star system of the same name.", + "postalCode": "BO-016", + "postOfficeBox": "Station 016", + "postalAddress": "EPFL OT EP-5 BESPIN $ Base 016 (Bâtiment Kamino) $ Station 016 $ BO-016" } }, { @@ -62,7 +68,10 @@ "Tatooine", "Tatooine est une planète désertique située dans les territoires de la bordure extérieure de la galaxie." ], - "ou;lang-en": "Tatooine is a desert planet located in the Outer Rim territories of the galaxy." + "ou;lang-en": "Tatooine is a desert planet located in the Outer Rim territories of the galaxy.", + "postalCode": "BO-001", + "postOfficeBox": "Station 001", + "postalAddress": "EPFL OT EP-6 TATOOINE $ Base 001 (Bâtiment Tatooine) $ Station 001 $ BO-001" } }, { @@ -84,7 +93,10 @@ "Mandalore", "Mandalore est une planète située dans les territoires de la bordure extérieure de la galaxie." ], - "ou;lang-en": "Mandalore is a planet located in the Outer Rim territories of the galaxy." + "ou;lang-en": "Mandalore is a planet located in the Outer Rim territories of the galaxy.", + "postalCode": "DI-231", + "postOfficeBox": "Station 231", + "postalAddress": "EPFL SO TV-3 MANDALORE $ Base 231 (Bâtiment Mandalore) $ Station 231 $ DI-231" } }, { @@ -106,7 +118,10 @@ "Coruscant", "Coruscant est une planète tellurique des Mondes du Noyau entièrement urbanisée et recouvertes d'infrastructures." ], - "ou;lang-en": "Coruscant is an ecumenopolis, collectively known as Imperial City in the Core Worlds." + "ou;lang-en": "Coruscant is an ecumenopolis, collectively known as Imperial City in the Core Worlds.", + "postalCode": "DI-Temple", + "postOfficeBox": "Station Temple", + "postalAddress": "EPFL SO TV-3 MANDALORE $ Base Temple (Bâtiment Coruscant) $ Station Temple $ Jedi Temple" } }, { @@ -128,7 +143,10 @@ "Mandalore", "Mandalore est une planète située dans les territoires de la bordure extérieure de la galaxie." ], - "ou;lang-en": "Mandalore is a planet located in the Outer Rim territories of the galaxy." + "ou;lang-en": "Mandalore is a planet located in the Outer Rim territories of the galaxy.", + "postalCode": "PA-001", + "postOfficeBox": "Station 001", + "postalAddress": "EPFL SO TV-3 MANDALORE $ Base 001 (Bâtiment Mandalore) $ Station 001 $ Ronion 001" } }, { @@ -150,7 +168,10 @@ "Kalevala", "Kalevala est une planète du système Mandalore située dans les territoires de la bordure extérieure." ], - "ou;lang-en": "Kalevala is a planet in the Mandalore system located in the Outer Rim territories." + "ou;lang-en": "Kalevala is a planet in the Mandalore system located in the Outer Rim territories.", + "postalCode": "BO-Kryze", + "postOfficeBox": "Station Kryze", + "postalAddress": "EPFL SO TV-4 KALEVALA $ Base Kryze (Bâtiment Kalevala) $ Station Kryze $ Castle Kryze" } } ] From e3a169c7396750ff703c9ce12824597750460a7f Mon Sep 17 00:00:00 2001 From: Azecko <30987143+Azecko@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:04:26 +0200 Subject: [PATCH 7/7] Release v0.1.0 (#104) --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afaeb33..b911f83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # CHANGELOG +### v0.1.0 / 2023-08-29 + +- Address route +- Handle ldap client errors +- Improve Docker image (speed and permissions) +- Update prettier from 2.8.7 to 3.0.1 +- Fix environment variables for Docker Compose +- Fix 'node' engine requirement +- Improve section deploy in documentation (Ansible) + ### v0.0.1 / 2023-08-02 - First version, released on an unsuspecting world. diff --git a/package.json b/package.json index 7322e12..59b8dd5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "search-api", "private": true, - "version": "0.0.1", + "version": "0.1.0", "description": "EPFL Search Engine API", "repository": "epfl-si/search-api", "author": "William Belle ",