From 2707b5fc429ebb2b98ea60f32b13ab2806f98438 Mon Sep 17 00:00:00 2001 From: Markus Nilsson Date: Mon, 16 Dec 2024 16:53:58 +0100 Subject: [PATCH 1/2] feature: Add environmental variables to config Solves issue: Environment variables for configuration (#195) --- conf/config.js | 134 ++++++++++++++++++++-------------------- conf/dbconfig.js | 60 +++++++++--------- lib/utils/configutil.js | 65 +++++++++++++++++++ 3 files changed, 164 insertions(+), 95 deletions(-) create mode 100644 lib/utils/configutil.js diff --git a/conf/config.js b/conf/config.js index 9514ad9..729ff1e 100644 --- a/conf/config.js +++ b/conf/config.js @@ -1,86 +1,88 @@ +var configutil = require('../lib/utils/configutil'); + module.exports = { mapState: { - 'storagePath': 'OrigoMapState' // Path to map state storage. Current path will save map state to a folder named OrigoMapState in the origo-server directory. + 'storagePath': process.env.ORIGOSERVER_MAPSTATE_STORAGEPATH ?? 'OrigoMapState' // Path to map state storage. Current path will save map state to a folder named OrigoMapState in the origo-server directory. }, getInskrivning: { - url: "https://api.lantmateriet.se/distribution/produkter/inskrivning/v3", - url_token: "https://api.lantmateriet.se/token", - consumer_key: '', - consumer_secret: '', - scope: 'inskrivning_direkt_v3_read' + url: process.env.ORIGOSERVER_GETINSKRIVNING_URL ?? "https://api.lantmateriet.se/distribution/produkter/inskrivning/v3", + url_token: process.env.ORIGOSERVER_GETINSKRIVNING_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_GETINSKRIVNING_CONSUMER_KEY ?? '', + consumer_secret: process.env.ORIGOSERVER_GETINSKRIVNING_CONSUMER_SECRET ?? '', + scope: process.env.ORIGOSERVER_GETINSKRIVNING_SCOPE ?? 'inskrivning_direkt_v3_read' }, getAkt: { - url_token: "https://api.lantmateriet.se/token", - consumer_key: '', - consumer_secret: '', - scope: 'am_application_scope default' + url_token: process.env.ORIGOSERVER_GETAKT_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_GETAKT_CONSUMER_KEY ?? '', + consumer_secret: process.env.ORIGOSERVER_GETAKT_CONSUMER_SECRET ?? '', + scope: process.env.ORIGOSERVER_GETAKT_SCOPE ?? 'am_application_scope default' }, proxy: { - proxyUrl: 'proxy?url=' + proxyUrl: process.env.ORIGOSERVER_PROXY_PROXYURL ?? 'proxy?url=' }, 'lmproxy-ver': { - url: "http://maps-ver.lantmateriet.se/", + url: process.env.ORIGOSERVER_LMPROXY_VER_URL ?? "http://maps-ver.lantmateriet.se/", auth: { - user: 'xxxxx', - pass: 'xxxxx' + user: process.env.ORIGOSERVER_LMPROXY_VER_AUTH_USER ?? 'xxxxx', + pass: process.env.ORIGOSERVER_LMPROXY_VER_AUTH_PASS ?? 'xxxxx' } }, lmproxy: { - url: "http://maps.lantmateriet.se/", + url: process.env.ORIGOSERVER_LMPROXY_URL ?? "http://maps.lantmateriet.se/", auth: { - user: 'xxxxx', - pass: 'xxxxx' + user: process.env.ORIGOSERVER_LMPROXY_AUTH_USER ?? 'xxxxx', + pass: process.env.ORIGOSERVER_LMPROXY_AUTH_PASS ?? 'xxxxx' } }, lmbuilding: { - url: 'https://api.lantmateriet.se/distribution/produkter/byggnad/v3', - url_token: "https://apimanager.lantmateriet.se/oauth2/token", - url_revoke: "https://apimanager.lantmateriet.se/oauth2/revoke", - consumer_key: 'xxxxx', - consumer_secret: 'xxxxx', - scope: 'byggnad_direkt_v3_read' + url: process.env.ORIGOSERVER_LMBUILDING_URL ?? 'https://api.lantmateriet.se/distribution/produkter/byggnad/v3', + url_token: process.env.ORIGOSERVER_LMBUILDING_URL_TOKEN ?? "https://apimanager.lantmateriet.se/oauth2/token", + url_revoke: process.env.ORIGOSERVER_LMBUILDING_URL_REVOKE ?? "https://apimanager.lantmateriet.se/oauth2/revoke", + consumer_key: process.env.ORIGOSERVER_LMBUILDING_CONSUMER_KEY ?? 'xxxxx', + consumer_secret: process.env.ORIGOSERVER_LMBUILDING_CONSUMER_SECRET ?? 'xxxxx', + scope: process.env.ORIGOSERVER_LMBUILDING_SCOPE ?? 'byggnad_direkt_v3_read' }, lmelevation: { - url: "https://api.lantmateriet.se/distribution/produkter/hojd/v1/rest/api", - url_token: "https://api.lantmateriet.se/token", - consumer_key: 'xxxxx', - consumer_secret: 'xxxxx', - scope: 'am_application_scope default' + url: process.env.ORIGOSERVER_LMELEVATION_URL ?? "https://api.lantmateriet.se/distribution/produkter/hojd/v1/rest/api", + url_token: process.env.ORIGOSERVER_LMELEVATION_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_LMELEVATION_CONSUMER_KEY ?? 'xxxxx', + consumer_secret: process.env.ORIGOSERVER_LMELEVATION_CONSUMER_SECRET ?? 'xxxxx', + scope: process.env.ORIGOSERVER_LMELEVATION_SCOPE ?? 'am_application_scope default' }, lmsearchplacename: { - url: "https://api.lantmateriet.se/distribution/produkter/ortnamn/v2.1", - url_token: "https://api.lantmateriet.se/token", - consumer_key: 'xxxxx', - consumer_secret: 'xxxxx', - scope: 'am_application_scope default' + url: process.env.ORIGOSERVER_LMSEARCHPLACENAME_URL ?? "https://api.lantmateriet.se/distribution/produkter/ortnamn/v2.1", + url_token: process.env.ORIGOSERVER_LMSEARCHPLACENAME_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_LMSEARCHPLACENAME_CONSUMER_KEY ?? 'xxxxx', + consumer_secret: process.env.ORIGOSERVER_LMSEARCHPLACENAME_CONSUMER_SECRET ?? 'xxxxx', + scope: process.env.ORIGOSERVER_LMSEARCHPLACENAME_SCOPE ?? 'am_application_scope default' }, lmsearchestate: { - url: "https://api.lantmateriet.se/distribution/produkter/registerbeteckning/v5/", - url_token: "https://api.lantmateriet.se/token", - consumer_key: 'xxxxx', - consumer_secret: 'xxxxx', - scope: 'registerbeteckning_direkt_v5_read' + url: process.env.ORIGOSERVER_LMSEARCHESTATE_URL ?? "https://api.lantmateriet.se/distribution/produkter/registerOOObeteckning/v5/", + url_token: process.env.ORIGOSERVER_LMSEARCHESTATE_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_LMSEARCHESTATE_CONSUMER_KEY ?? 'xxxxx', + consumer_secret: process.env.ORIGOSERVER_LMSEARCHESTATE_CONSUMER_SECRET ?? 'xxxxx', + scope: process.env.ORIGOSERVER_LMSEARCHESTATE_SCOPE ?? 'registerbeteckning_direkt_v5_read' }, lmsearchaddress: { - url: "https://api.lantmateriet.se/distribution/produkter/belagenhetsadress/v4.2", - url_token: "https://api.lantmateriet.se/token", - consumer_key: 'xxxxx', - consumer_secret: 'xxxxx', - scope: 'belagenhetsadress_direkt_v42_read' + url: process.env.ORIGOSERVER_LMSEARCHADDRESS_URL ?? "https://api.lantmateriet.se/distribution/produkter/belagenhetsadress/v4.2", + url_token: process.env.ORIGOSERVER_LMSEARCHADDRESS_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_LMSEARCHADDRESS_CONSUMER_KEY ?? 'xxxxx', + consumer_secret: process.env.ORIGOSERVER_LMSEARCHADDRESS_CONSUMER_SECRET ?? 'xxxxx', + scope: process.env.ORIGOSERVER_LMSEARCHADDRESS_SCOPE ?? 'belagenhetsadress_direkt_v42_read' }, lmgetestate: { - url: "https://api.lantmateriet.se/distribution/produkter/fastighetsamfallighet/v3.1", - url_token: "https://api.lantmateriet.se/token", - consumer_key: 'xxxxx', - consumer_secret: 'xxxxx', - scope: 'fastighetochsamfallighet_direkt_v31_read' + url: process.env.ORIGOSERVER_LMGETESTATE_URL ?? "https://api.lantmateriet.se/distribution/produkter/fastighetsamfallighet/v3.1", + url_token: process.env.ORIGOSERVER_LMGETESTATE_URL_TOKEN ?? "https://api.lantmateriet.se/token", + consumer_key: process.env.ORIGOSERVER_LMGETESTATE_CONSUMER_KEY ?? 'xxxxx', + consumer_secret: process.env.ORIGOSERVER_LMGETESTATE_CONSUMER_SECRET ?? 'xxxxx', + scope: process.env.ORIGOSERVER_LMGETESTATE_SCOPE ?? 'fastighetochsamfallighet_direkt_v31_read' }, cors: { - origin: '*', + origin: process.env.ORIGOSERVER_CORS_ORIGIN ?? '*', methods: ['GET', 'PUT', 'POST', 'OPTIONS', 'PATCH', 'DELETE'], - headers: 'X-Requested-With,content-type', - credentials: true, - optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 + headers: process.env.ORIGOSERVER_CORS_HEADERS ?? 'X-Requested-With,content-type', + credentials: configutil.convertToBoolean(process.env.ORIGOSERVER_CORS_CREDENTIALS) ?? true, + optionsSuccessStatus: configutil.convertToNumber(process.env.ORIGOSERVER_CORS_OPTIONSSUCCESSSTATUS) ?? 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 }, 'iotproxy': { services: [ @@ -129,23 +131,23 @@ module.exports = { ] }, auth: { - openidIssuer: 'https://openid-provider/.well-known/openid-configuration', - redirect_uri: 'https://karta.xxx.se', - http_timeout: 10000, - client_id: 'xxxxx', - client_secret: 'xxxxx', - display_name: 'samaccountname', + openidIssuer: process.env.ORIGOSERVER_AUTH_OPENIDISSUER ?? 'https://openid-provider/.well-known/openid-configuration', + redirect_uri: process.env.ORIGOSERVER_AUTH_REDIRECT_URI ?? 'https://karta.xxx.se', + http_timeout: configutil.convertToNumber(process.env.ORIGOSERVER_AUTH_HTTP_TIMEOUT) ?? 10000, + client_id: process.env.ORIGOSERVER_AUTH_CLIENT_ID ?? 'xxxxx', + client_secret: process.env.ORIGOSERVER_AUTH_CLIENT_SECRET ?? 'xxxxx', + display_name: process.env.ORIGOSERVER_AUTH_DISPLAY_NAME ?? 'samaccountname', clients: { - my_client: 'https://www.myclient.se', - my_other_client: 'https://www.myotherclient.com' + my_client: process.env.ORIGOSERVER_AUTH_MY_CLIENT ?? 'https://www.myclient.se', + my_other_client: process.env.ORIGOSERVER_AUTH_MY_OTHER_CLIENT ?? 'https://www.myotherclient.com' } }, ngpDetaljplan: { - url_base: "https://api.lantmateriet.se/", - client_key: 'xxxxx', - client_secret: 'xxxxx', - grant_type: 'client_credentials', - scope: 'am_application_scope default', - query: '{"feature.typ": {"eq": "detaljplan"}, "detaljplan.objektidentitet": {"eq": "$planid$"}, "detaljplan.status": {"in": ["laga kraft"]}}' + url_base: process.env.ORIGOSERVER_NGPDETALJPLAN_URL_BASE ?? "https://api.lantmateriet.se/", + client_key: process.env.ORIGOSERVER_NGPDETALJPLAN_CLIENT_KEY ?? 'xxxxx', + client_secret: process.env.ORIGOSERVER_NGPDETALJPLAN_CLIENT_SECRET ?? 'xxxxx', + grant_type: process.env.ORIGOSERVER_NGPDETALJPLAN_GRANT_TYPE ?? 'client_credentials', + scope: process.env.ORIGOSERVER_NGPDETALJPLAN_SCOPE ?? 'am_application_scope default', + query: process.env.ORIGOSERVER_NGPDETALJPLAN_QUERY ?? '{"feature.typ": {"eq": "detaljplan"}, "detaljplan.objektidentitet": {"eq": "$planid$"}, "detaljplan.status": {"in": ["laga kraft"]}}' } } diff --git a/conf/dbconfig.js b/conf/dbconfig.js index 8501b02..b53a967 100644 --- a/conf/dbconfig.js +++ b/conf/dbconfig.js @@ -1,21 +1,23 @@ +var configutil = require('../lib/utils/configutil'); + module.exports = { limit: 10, connectors: { addressEstate: { mssql: { - user: 'xxxxx', - password: 'xxxxx', - connectString: "server name", - database: "database name" + user: process.env.ORIGOSERVER_CONNECTORS_ADDRESSESTATE_MSSQL_USER ?? 'xxxxx', + password: process.env.ORIGOSERVER_CONNECTORS_ADDRESSESTATE_MSSQL_PASSWORD ?? 'xxxxx', + connectString: process.env.ORIGOSERVER_CONNECTORS_ADDRESSESTATE_MSSQL_CONNECTSTRING ?? "server name", + database: process.env.ORIGOSERVER_CONNECTORS_ADDRESSESTATE_MSSQL_DATABASE ?? "database name" } }, search: { pg: { - user: 'postgres', - password: 'postgres', - connectString: "localhost", - database: "mdk", - port: 5432 + user: process.env.ORIGOSERVER_CONNECTORS_SEARCH_PG_USER ?? 'postgres', + password: process.env.ORIGOSERVER_CONNECTORS_SEARCH_PG_PASSWORD ?? 'postgres', + connectString: process.env.ORIGOSERVER_CONNECTORS_SEARCH_PG_CONNECTSTRING ?? "localhost", + database: process.env.ORIGOSERVER_CONNECTORS_SEARCH_PG_DATABASE ?? "mdk", + port: configutil.convertToNumber(process.env.ORIGOSERVER_CONNECTORS_SEARCH_PG_PORT) ?? 5432 } }, singlesearch: { @@ -31,11 +33,11 @@ module.exports = { // database: "database name" // } pg: { - user: 'postgres', - password: 'postgres', - connectString: "localhost", - database: "rtj", - port: 5432 + user: process.env.ORIGOSERVER_CONNECTORS_SINGLESEARCH_PG_USER ?? 'postgres', + password: process.env.ORIGOSERVER_CONNECTORS_SINGLESEARCH_PG_PASSWORD ?? 'postgres', + connectString: process.env.ORIGOSERVER_CONNECTORS_SINGLESEARCH_PG_CONNECTSTRING ?? "localhost", + database: process.env.ORIGOSERVER_CONNECTORS_SINGLESEARCH_PG_DATABASE ?? "rtj", + port: configutil.convertToNumber(process.env.ORIGOSERVER_CONNECTORS_SINGLESEARCH_PG_PORT) ?? 5432 } } }, @@ -49,11 +51,11 @@ module.exports = { // useCentroid: true // } search: { - table: "fastighetsytor_sammanslagen", - searchField: "FASTIGHET", - schema: 'public', - geometryName: 'geom', - useCentroid: true + table: process.env.ORIGOSERVER_MODELS_SINGLESEARCH_TABLE ?? "fastighetsytor_sammanslagen", + searchField: process.env.ORIGOSERVER_MODELS_SINGLESEARCH_SEARCHFIELD ?? "FASTIGHET", + schema: process.env.ORIGOSERVER_MODELS_SINGLESEARCH_SCHEMA ?? 'public', + geometryName: process.env.ORIGOSERVER_MODELS_SINGLESEARCH_GEOMETRYNAME ?? 'geom', + useCentroid: configutil.convertToBoolean(process.env.ORIGOSERVER_MODELS_SINGLESEARCH_USECENTROID) ?? true } }, @@ -79,19 +81,19 @@ module.exports = { }, addressEstate: { addresses: { - table: "table name", - searchField: "search field name", - schema: 'schema name, for example dbo', - database: 'database name', - useCentroid: true, + table: process.env.ORIGOSERVER_MODELS_ADDRESSESTATE_ADDRESSES_TABLE ?? "table name", + searchField: process.env.ORIGOSERVER_MODELS_ADDRESSESTATE_ADDRESSES_SEARCHFIELD ?? "search field name", + schema: process.env.ORIGOSERVER_MODELS_ADDRESSESTATE_ADDRESSES_SCHEMA ?? 'schema name, for example dbo', + database: process.env.ORIGOSERVER_MODELS_ADDRESSESTATE_ADDRESSES_DATABASE ?? 'database name', + useCentroid: configutil.convertToBoolean(process.env.ORIGOSERVER_MODELS_ADDRESSESTATE_ADDRESSES_USECENTROID) ?? true, fields: ['field name', 'field name'] }, estates: { - table: "table name", - searchField: "search field name", - schema: 'schema name, for example dbo', - database: 'database name', - useCentroid: true, + table: process.env.ORIGOSERVER_models_addressEstate_estates_table ?? "table name", + searchField: process.env.ORIGOSERVER_models_addressEstate_estates_searchField ?? "search field name", + schema: process.env.ORIGOSERVER_models_addressEstate_estates_schema ?? 'schema name, for example dbo', + database: process.env.ORIGOSERVER_models_addressEstate_estates_database ?? 'database name', + useCentroid: configutil.convertToBoolean(process.env.ORIGOSERVER_models_addressEstate_estates_useCentroid) ?? true, fields: ['field name', 'field name'] } } diff --git a/lib/utils/configutil.js b/lib/utils/configutil.js new file mode 100644 index 0000000..3ef4f81 --- /dev/null +++ b/lib/utils/configutil.js @@ -0,0 +1,65 @@ +var Configutil = function() { + + /** + * Converts a string value to a number value. The value + * undefined is returned if the string doesn't contain a + * number. + * + * @param value: The value to convert to Number. + * @return {Number} Returns the value as the type Number, + * or undefined. + */ + function convertToNumber(value) { + var defaultResult = undefined; + + if (value == null) { + return defaultResult; + } + + const number = Number(value); + return isNaN(number) ? defaultResult : number; + } + + /** + * Converts a string value to a boolean value. The value needs + * to be "true" or "false", and the matching to these values is + * case insensitive. Other input makes this funtion return + * undefined. + * + * @param value: The value to convert to Bboolean. + * @return {Boolean} Returns true, false or undefined. + */ + function convertToBoolean(value) { + var defaultResult = undefined; + + if (value == null) { + return defaultResult; + } + + const stringValue = String(value).toLowerCase(); + + if (stringValue === 'true') { + return true; + } + else if (stringValue === 'false') { + return false; + } + else { + return defaultResult; + } +} + + return { + + convertToNumber: function(value) { + return convertToNumber(value); + }, + convertToBoolean: function(value) { + return convertToBoolean(value); + } + + }; + +} + +module.exports = Configutil(); From 3e8c730dd9d288f319dccc6435d69b7d84db16be Mon Sep 17 00:00:00 2001 From: Markus Nilsson Date: Mon, 16 Dec 2024 17:53:35 +0100 Subject: [PATCH 2/2] Throws errors in config parser functions Modification to the solution of issue: Environment variables for configuration (#195) --- lib/utils/configutil.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/utils/configutil.js b/lib/utils/configutil.js index 3ef4f81..368df10 100644 --- a/lib/utils/configutil.js +++ b/lib/utils/configutil.js @@ -1,11 +1,11 @@ var Configutil = function() { /** - * Converts a string value to a number value. The value - * undefined is returned if the string doesn't contain a - * number. + * Converts a string value to a number value. Returns undefined if + * value is null or undefined. * * @param value: The value to convert to Number. + * @throws {Error} If the value can't be parsed to Number. * @return {Number} Returns the value as the type Number, * or undefined. */ @@ -13,27 +13,33 @@ var Configutil = function() { var defaultResult = undefined; if (value == null) { - return defaultResult; + return defaultResult; } const number = Number(value); - return isNaN(number) ? defaultResult : number; + if (isNaN(number)){ + throw new Error("The function convertToNumber failed to convert value to number."); + } + else { + return number; + } } /** * Converts a string value to a boolean value. The value needs * to be "true" or "false", and the matching to these values is - * case insensitive. Other input makes this funtion return + * case insensitive. Returns undefined if value is null or * undefined. * - * @param value: The value to convert to Bboolean. + * @param value: The value to convert to Boolean. + * @throws {Error} If the value can't be parsed to Boolean. * @return {Boolean} Returns true, false or undefined. */ function convertToBoolean(value) { var defaultResult = undefined; if (value == null) { - return defaultResult; + return defaultResult; } const stringValue = String(value).toLowerCase(); @@ -45,7 +51,7 @@ var Configutil = function() { return false; } else { - return defaultResult; + throw new Error("The function convertToBoolean failed to convert value to boolean."); } }