@sap/async-xsjs 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +37 -0
  3. package/README.md +445 -0
  4. package/differences.md +162 -0
  5. package/docs/$.Application.html +262 -0
  6. package/docs/$.Session.html +674 -0
  7. package/docs/$.db.CallableStatement.html +2524 -0
  8. package/docs/$.db.Connection.html +511 -0
  9. package/docs/$.db.ParameterMetaData.html +805 -0
  10. package/docs/$.db.PreparedStatement.html +1796 -0
  11. package/docs/$.db.ResultSet.html +1308 -0
  12. package/docs/$.db.ResultSetMetaData.html +800 -0
  13. package/docs/$.db.SQLException.html +259 -0
  14. package/docs/$.db.html +773 -0
  15. package/docs/$.hdb.ColumnMetadata.html +438 -0
  16. package/docs/$.hdb.Connection.html +663 -0
  17. package/docs/$.hdb.ProcedureResult.html +280 -0
  18. package/docs/$.hdb.ResultSet.html +324 -0
  19. package/docs/$.hdb.ResultSetIterator.html +315 -0
  20. package/docs/$.hdb.ResultSetMetaData.html +259 -0
  21. package/docs/$.hdb.SQLException.html +259 -0
  22. package/docs/$.hdb.html +557 -0
  23. package/docs/$.html +471 -0
  24. package/docs/$.jobs.Job.html +783 -0
  25. package/docs/$.jobs.JobLog.html +380 -0
  26. package/docs/$.jobs.JobSchedules.html +852 -0
  27. package/docs/$.jobs.html +238 -0
  28. package/docs/$.net.Destination.html +304 -0
  29. package/docs/$.net.Mail.Part.html +510 -0
  30. package/docs/$.net.Mail.html +504 -0
  31. package/docs/$.net.SMTPConnection.html +347 -0
  32. package/docs/$.net.html +749 -0
  33. package/docs/$.net.http.Client.html +562 -0
  34. package/docs/$.net.http.Destination.html +237 -0
  35. package/docs/$.net.http.Request.html +567 -0
  36. package/docs/$.net.http.html +292 -0
  37. package/docs/$.security.AntiVirus.html +361 -0
  38. package/docs/$.security.Store.html +636 -0
  39. package/docs/$.security.crypto.html +414 -0
  40. package/docs/$.security.html +247 -0
  41. package/docs/$.security.x509.html +373 -0
  42. package/docs/$.text.analysis.Session.html +983 -0
  43. package/docs/$.text.analysis.html +242 -0
  44. package/docs/$.text.html +246 -0
  45. package/docs/$.text.mining.Session.html +2018 -0
  46. package/docs/$.text.mining.html +242 -0
  47. package/docs/$.trace.html +525 -0
  48. package/docs/$.util.SAXParser.html +955 -0
  49. package/docs/$.util.Zip.html +474 -0
  50. package/docs/$.util.codec.html +414 -0
  51. package/docs/$.util.compression.html +357 -0
  52. package/docs/$.util.html +325 -0
  53. package/docs/$.util.sql.html +290 -0
  54. package/docs/$.web.Body.html +333 -0
  55. package/docs/$.web.EntityList.html +296 -0
  56. package/docs/$.web.TupelList.html +496 -0
  57. package/docs/$.web.WebEntityRequest.html +393 -0
  58. package/docs/$.web.WebEntityResponse.html +392 -0
  59. package/docs/$.web.WebRequest.html +560 -0
  60. package/docs/$.web.WebResponse.html +609 -0
  61. package/docs/$.web.html +246 -0
  62. package/docs/Copyright-SAP.html +39 -0
  63. package/docs/Disclaimer-SAP.html +55 -0
  64. package/docs/index.html +232 -0
  65. package/docs/styles/jsdoc-default.css +382 -0
  66. package/lib/AppConfig.js +36 -0
  67. package/lib/AuditLogger.js +41 -0
  68. package/lib/cacert.js +26 -0
  69. package/lib/ctypes.js +153 -0
  70. package/lib/destinations/dest-provider.js +57 -0
  71. package/lib/index.js +235 -0
  72. package/lib/jobs/Action.js +40 -0
  73. package/lib/jobs/Job.js +100 -0
  74. package/lib/jobs/JobManager.js +150 -0
  75. package/lib/jobs/JobsRuntime.js +133 -0
  76. package/lib/jobs/SqlScriptJobRunner.js +36 -0
  77. package/lib/jobs/XsjsJobRunner.js +78 -0
  78. package/lib/jobs/index.js +11 -0
  79. package/lib/logging.js +16 -0
  80. package/lib/middleware.js +125 -0
  81. package/lib/odata/ODataService.js +125 -0
  82. package/lib/odata/index.js +7 -0
  83. package/lib/odata/service-factory.js +26 -0
  84. package/lib/passport-noauth.js +17 -0
  85. package/lib/routes.js +115 -0
  86. package/lib/runtime.js +740 -0
  87. package/lib/sandbox.js +40 -0
  88. package/lib/utils/XsJsFunctionRunner.js +57 -0
  89. package/lib/utils/XsJsLibFunctionRunner.js +57 -0
  90. package/lib/utils/buffer-utils.js +77 -0
  91. package/lib/utils/compression-utils.js +14 -0
  92. package/lib/utils/date-utils.js +104 -0
  93. package/lib/utils/errors/HttpError.js +20 -0
  94. package/lib/utils/errors/wrap-app-error.js +18 -0
  95. package/lib/utils/index.js +17 -0
  96. package/lib/utils/xs-function-runner.js +51 -0
  97. package/lib/utils/xs-types.js +21 -0
  98. package/lib/utils/xspath.js +36 -0
  99. package/lib/utils/xsstack.js +28 -0
  100. package/lib/views/error.html +28 -0
  101. package/lib/xsjs/Application.js +28 -0
  102. package/lib/xsjs/Locale.js +53 -0
  103. package/lib/xsjs/Session.js +31 -0
  104. package/lib/xsjs/constants.js +71 -0
  105. package/lib/xsjs/db/common/DbBase.js +85 -0
  106. package/lib/xsjs/db/common/DbOptions.js +163 -0
  107. package/lib/xsjs/db/common/arguments-validation.js +102 -0
  108. package/lib/xsjs/db/common/connection.js +12 -0
  109. package/lib/xsjs/db/common/enums.js +93 -0
  110. package/lib/xsjs/db/common/execute-batch.js +38 -0
  111. package/lib/xsjs/db/common/parse-time.js +139 -0
  112. package/lib/xsjs/db/dbapi/CallableStatement.js +192 -0
  113. package/lib/xsjs/db/dbapi/Connection.js +78 -0
  114. package/lib/xsjs/db/dbapi/DB.js +39 -0
  115. package/lib/xsjs/db/dbapi/ParameterMetaData.js +118 -0
  116. package/lib/xsjs/db/dbapi/PreparedStatement.js +78 -0
  117. package/lib/xsjs/db/dbapi/ResultSet.js +220 -0
  118. package/lib/xsjs/db/dbapi/ResultSetMetaData.js +116 -0
  119. package/lib/xsjs/db/dbapi/Statement.js +514 -0
  120. package/lib/xsjs/db/dbapi/conversions.js +113 -0
  121. package/lib/xsjs/db/dbapi/fetch-rows.js +32 -0
  122. package/lib/xsjs/db/hdbapi/Connection.js +525 -0
  123. package/lib/xsjs/db/hdbapi/HDB.js +32 -0
  124. package/lib/xsjs/db/hdbapi/ResultSetIterator.js +40 -0
  125. package/lib/xsjs/db/hdbapi/convert.js +77 -0
  126. package/lib/xsjs/db/hdbapi/table-string-parser.js +52 -0
  127. package/lib/xsjs/db/index.js +4 -0
  128. package/lib/xsjs/index.js +13 -0
  129. package/lib/xsjs/jobs/Job.js +228 -0
  130. package/lib/xsjs/jobs/Jobs.js +11 -0
  131. package/lib/xsjs/jobs/Logs.js +127 -0
  132. package/lib/xsjs/jobs/Schedule.js +110 -0
  133. package/lib/xsjs/jobs/Schedules.js +108 -0
  134. package/lib/xsjs/net/Destination.js +43 -0
  135. package/lib/xsjs/net/http/Client.js +220 -0
  136. package/lib/xsjs/net/http/HTTP.js +72 -0
  137. package/lib/xsjs/net/index.js +5 -0
  138. package/lib/xsjs/net/smtp/Mail.js +38 -0
  139. package/lib/xsjs/net/smtp/Part.js +30 -0
  140. package/lib/xsjs/net/smtp/SMTPConnection.js +39 -0
  141. package/lib/xsjs/net/smtp/index.js +18 -0
  142. package/lib/xsjs/net/smtp/nodemailer-util.js +77 -0
  143. package/lib/xsjs/require.js +39 -0
  144. package/lib/xsjs/security/AntiVirus.js +31 -0
  145. package/lib/xsjs/security/Store.js +119 -0
  146. package/lib/xsjs/security/crypto.js +23 -0
  147. package/lib/xsjs/security/index.js +5 -0
  148. package/lib/xsjs/security/x509.js +12 -0
  149. package/lib/xsjs/text/analysis/Session.js +128 -0
  150. package/lib/xsjs/text/index.js +30 -0
  151. package/lib/xsjs/text/mining/Session.js +82 -0
  152. package/lib/xsjs/trace/trace.js +41 -0
  153. package/lib/xsjs/util/SAXParser.js +174 -0
  154. package/lib/xsjs/util/Zip.js +220 -0
  155. package/lib/xsjs/util/codec.js +33 -0
  156. package/lib/xsjs/util/compression.js +24 -0
  157. package/lib/xsjs/util/index.js +22 -0
  158. package/lib/xsjs/web/BasicWebEntity.js +41 -0
  159. package/lib/xsjs/web/EntityList.js +11 -0
  160. package/lib/xsjs/web/TupelLists/CookiesTupelList.js +47 -0
  161. package/lib/xsjs/web/TupelLists/HeadersTupelList.js +55 -0
  162. package/lib/xsjs/web/TupelLists/ParametersTupelList.js +83 -0
  163. package/lib/xsjs/web/TupelLists/TupelListBase.js +45 -0
  164. package/lib/xsjs/web/WebBody.js +135 -0
  165. package/lib/xsjs/web/WebEntityRequest.js +40 -0
  166. package/lib/xsjs/web/WebEntityResponse.js +26 -0
  167. package/lib/xsjs/web/WebRequest.js +209 -0
  168. package/lib/xsjs/web/WebResponse.js +183 -0
  169. package/lib/xsjs/web/index.js +4 -0
  170. package/lib/xsjs/web/utils/HeadersParser.js +53 -0
  171. package/lib/xsjs/web/utils/HttpRequestParser.js +93 -0
  172. package/lib/xsjs/web/utils/MultipartParser.js +163 -0
  173. package/lib/xsjs/web/utils/MultipartResponseBuilder.js +73 -0
  174. package/lib/xsjs/web/utils/SetCookieParser.js +32 -0
  175. package/lib/xsjslib/TextBundleWrapper.js +46 -0
  176. package/lib/xsjslib/index.js +11 -0
  177. package/npm-shrinkwrap.json +11540 -0
  178. package/package.json +84 -0
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ var _ = require('lodash');
4
+ var util = require('util');
5
+ // var fiber = require('@sap/fibers');
6
+
7
+ module.exports = XsjsJobRunner;
8
+
9
+ function XsjsJobRunner(rt) {
10
+ if (!rt) {
11
+ throw new Error('Valid xsjs runtime expected');
12
+ }
13
+ this._rt = rt;
14
+ this._module = null;
15
+ this._jsFunction = null;
16
+ }
17
+
18
+ XsjsJobRunner.prototype.prepare = async function(job, req, runId) {
19
+ this._cleanup();
20
+ this._assertValidJob(job);
21
+
22
+ var rt = this._rt;
23
+ var jsPath = job.action.getScriptPath();
24
+
25
+ var context = rt.createBaseContext(req, null, { id: runId, location: job.urlPath });
26
+ try {
27
+ var module = await rt.runXsjs(jsPath, context);
28
+ } finally {
29
+ rt.cleanupContext(context);
30
+ }
31
+
32
+ var funcName = job.action.funcname;
33
+ var jsFunction = module.namespace.default[funcName];
34
+ if (!jsFunction) {
35
+ throw new Error(util.format('XSJS "%s" doesn\'t have a function "%s"', jsPath, funcName));
36
+ }
37
+ if (!_.isFunction(jsFunction)) {
38
+ throw new Error(util.format('"%s" is not a function in "%s"', funcName, jsPath));
39
+ }
40
+
41
+ this._module = module;
42
+ this._jsFunction = jsFunction;
43
+ };
44
+
45
+ /**
46
+ * Runs asynchronously
47
+ * @param inputParams to be provided to XSJS function
48
+ * @param done callback to notify when job finished
49
+ */
50
+ XsjsJobRunner.prototype.run = async function(inputParams) {
51
+ if (!this._jsFunction) {
52
+ throw new Error('XsjsJobRunner: runner needs to be prepared before run is called');
53
+ }
54
+
55
+ var self = this;
56
+ try {
57
+ await self._jsFunction.call(this, inputParams || {});
58
+ }
59
+ finally {
60
+ self._cleanup();
61
+ self._rt.triggerGc();
62
+ }
63
+ };
64
+
65
+ XsjsJobRunner.prototype._assertValidJob = function(job) {
66
+ if (!job) {
67
+ throw new TypeError('Valid job object should be provided');
68
+ }
69
+
70
+ if (!job.action.isJavaScript()) {
71
+ throw new TypeError('Not a handler for SQL procedure based jobs, xsjob: ' + job.urlPath);
72
+ }
73
+ };
74
+
75
+ XsjsJobRunner.prototype._cleanup = function() {
76
+ this._module = null;
77
+ this._jsFunction = null;
78
+ };
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var Job = require('./Job');
4
+ var Action = require('./Action');
5
+ var JobManager = require('./JobManager');
6
+ var JobsRuntime = require('./JobsRuntime');
7
+
8
+ module.exports.Action = Action;
9
+ module.exports.Job = Job;
10
+ module.exports.JobManager = JobManager;
11
+ module.exports.JobsRuntime = JobsRuntime;
package/lib/logging.js ADDED
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var logging = require('@sap/logging');
4
+
5
+ var CATEGORY = '/CompatibilityLayer';
6
+ var appContext = logging.createAppContext({ csnComponent: 'BC-XS-JS' });
7
+ var logContext = appContext.createLogContext({ id: '' });
8
+ var logger = logContext.getLogger(CATEGORY);
9
+ logger.warn = logger.warning;
10
+
11
+ module.exports = {
12
+ CATEGORY: CATEGORY,
13
+ appContext: appContext,
14
+ logger: logger,
15
+ tracer: logContext.getTracer(__filename)
16
+ };
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+
3
+ var _ = require('lodash');
4
+ var parseUrl = require('url').parse;
5
+ var parseQuery = require('querystring').parse;
6
+ var multiparty = require('multiparty');
7
+ var bodyParser = require('body-parser');
8
+ var mediaTyper = require('media-typer');
9
+ // var fibrous = require('@sap/fibrous');
10
+ var Locale = require('./xsjs/Locale');
11
+ var HttpError = require('./utils/errors/HttpError');
12
+
13
+ function getRewriteRule(rewriteRules, path) {
14
+ rewriteRules = rewriteRules || [];
15
+ path = path || '';
16
+ while (path.length) {
17
+ if (rewriteRules[path]) {
18
+ return rewriteRules[path];
19
+ }
20
+ if (path === '/') {
21
+ break;
22
+ }
23
+ var lastSlash = path.lastIndexOf('/');
24
+ path = lastSlash > 0 ? path.substring(0, lastSlash) : '/';
25
+ }
26
+ return [];
27
+ }
28
+
29
+ exports.urlRewrite = function (rt) {
30
+ return function urlRewriteMiddleware(req, res, next) {
31
+ var url = parseUrl(req.url);
32
+ var rule = _.find(getRewriteRule(rt.rewriteRules, url.pathname), function (rule) {
33
+ return rule.regex.test(url.pathname);
34
+ });
35
+ if (rule) {
36
+ var newUrl = parseUrl(url.pathname.replace(rule.regex, rule.replacement));
37
+ url.pathname = newUrl.pathname;
38
+ if (newUrl.query) {
39
+ if (url.query) {
40
+ url.query = [newUrl.query, url.query].join('&');
41
+ } else {
42
+ url.query = newUrl.query;
43
+ }
44
+ req.query = parseQuery(url.query);
45
+ url.search = '?' + url.query;
46
+ }
47
+ req.url = url.format();
48
+ req.loggingContext.getTracer(__filename).info(
49
+ 'Applying rewrite rule: "%s" to "%s" for URL "%s" - result "%s"',
50
+ rule.regex.source, rule.replacement, req.originalUrl, req.url
51
+ );
52
+
53
+ }
54
+ next();
55
+ };
56
+ };
57
+
58
+ exports.locale = function (req, res, next) {
59
+ res.locals.locale = new Locale(req);
60
+ next();
61
+ };
62
+
63
+ exports.multipartFormData = function (rt, req, res, next) {
64
+ var form = createFormObject(rt);
65
+ form.parse(req, function (err, fields, files) {
66
+ if (err) {
67
+ return next(err);
68
+ }
69
+ req['form-data'] = {
70
+ fields: fields,
71
+ files: files
72
+ };
73
+ next();
74
+ });
75
+ };
76
+
77
+ function createFormObject(rt) {
78
+ var formData = rt.get('formData');
79
+ return new multiparty.Form({maxFilesSize: formData.maxFilesSizeInBytes});
80
+ }
81
+
82
+ exports.textBody = function (options, req, res, next) {
83
+ var maxBodySize = (options && options.maxBodySize) || '1mb';
84
+ var contentType = req.headers['content-type'] || 'application/octet-stream';
85
+ var charset = mediaTyper.parse(contentType).parameters.charset;
86
+ function done(err) {
87
+ if (err) {
88
+ return next(err);
89
+ }
90
+ if (req.is(['urlencoded'])) {
91
+ req['form-urlencoded'] = parseQuery(req.body.toString());
92
+ }
93
+ next();
94
+ }
95
+ var bodyParserOptions = {
96
+ limit: maxBodySize,
97
+ type: function () { return true; }
98
+ };
99
+ bodyParser[charset ? 'text' : 'raw'](bodyParserOptions)(req, res, done);
100
+ };
101
+
102
+ exports.anyBody = function(rt, options) {
103
+ return function (req, res, next) {
104
+ if (req.is(['multipart/form-data'])) {
105
+ return exports.multipartFormData(rt, req, res, next);
106
+ }
107
+ exports.textBody(options, req, res, next);
108
+ };
109
+ };
110
+
111
+ exports.xsjs = function (rt) {
112
+ return function contextMiddleware(req, res, next) {
113
+ var endOfScriptName = req.path.indexOf('.xsjs') + '.xsjs'.length;
114
+ var pathToScript = req.path.substring(0, endOfScriptName);
115
+ res.locals.pathToScript = pathToScript;
116
+
117
+ rt.attachContext(req, res, { location: pathToScript });
118
+ // fibrous.middleware(req, res, next);
119
+ next();
120
+ };
121
+ };
122
+
123
+ exports.notFound = function (req, res, next) {
124
+ next(new HttpError(404, 'Not Found'));
125
+ };
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+
3
+ var assert = require('assert');
4
+ var odata = require('@sap/xsodata');
5
+ var createTrace = require('../xsjs/trace/trace').createTrace;
6
+ var db = require('../xsjs/db/common/connection');
7
+ var Connection = require('../xsjs/db/dbapi/Connection');
8
+ var utils = require('../utils');
9
+ var logging = require('../logging');
10
+ var format = require('util').format;
11
+ var wrapAppError = require('../utils/errors/wrap-app-error');
12
+
13
+ module.exports = ODataService;
14
+
15
+
16
+ function ODataService(rt, rootUriPath, filePath) {
17
+ assert(rt, 'valid runtime is required');
18
+ assert(rootUriPath, 'valid odata root uri path is required');
19
+ assert(filePath, 'valid xsodata file is required');
20
+
21
+ this._rt = rt;
22
+ this._rootUriPath = rootUriPath;
23
+ this._filePath = filePath;
24
+ this._handlers = {};
25
+ }
26
+
27
+ ODataService.prototype.getRootUriPath = function () {
28
+ return this._rootUriPath;
29
+ };
30
+
31
+ ODataService.prototype.handle = function (req, res, callback) {
32
+ assert(req, 'valid request object expected');
33
+ assert(res, 'valid response object is expected');
34
+
35
+ var self = this;
36
+ var cb = callback || function () { };
37
+ var tenant = req.authInfo && req.authInfo.getZoneId();
38
+
39
+ this._retrieveDbOptions(req, res, function (err, hanaOptions) {
40
+ if (err) {
41
+ return cb(err);
42
+ }
43
+
44
+ var context = self._createRequestContext(req, res, hanaOptions);
45
+ var handler = self._getHandler(tenant, hanaOptions.schema);
46
+ handler.processRequest(req, res, context.requestOptions, function (err) {
47
+ var clientWrapper = context.clientWrapper;
48
+ clientWrapper.client && clientWrapper.client.close(function () { }); // ignoring an error here
49
+ cb(err);
50
+ });
51
+ });
52
+ };
53
+
54
+ ODataService.prototype._getHandler = function (tenant, schema) {
55
+ if (this._handlers[tenant]) {
56
+ return this._handlers[tenant];
57
+ }
58
+
59
+ var config = {
60
+ serviceConfiguration: this._filePath,
61
+ defaultSchema: schema
62
+ };
63
+ var handler = new odata.ODataHandler(config);
64
+ this._handlers[tenant] = handler;
65
+ return handler;
66
+ };
67
+
68
+ ODataService.prototype._createRequestContext = function (req, res, hanaOptions) {
69
+ var self = this;
70
+ var rt = this._rt;
71
+ var locale = res.locals.locale;
72
+ var clientWrapper = { client: null };
73
+
74
+ function retrieveClient(config, cb) {
75
+ db.connect(hanaOptions)
76
+ .then((client) => {
77
+ clientWrapper.client = client;
78
+ cb(null, client);
79
+ })
80
+ .catch((err) => { cb(err); });
81
+ }
82
+
83
+ function odataExitRunner(fnDescriptor, param, cb) {
84
+ assert(clientWrapper.client, 'valid database client expected');
85
+ param.connection = new Connection(clientWrapper.client);
86
+ try {
87
+ var jsContext = rt.createBaseContext(req, locale, { location: self._rootUriPath });
88
+ var libId = utils.toXSObjectId(fnDescriptor.package, fnDescriptor.file);
89
+ var thisArg = utils.createXsFunctionThisArg(jsContext);
90
+
91
+ var xsFunctionRunner = new utils.XsJsLibFunctionRunner(rt, libId, jsContext);
92
+ xsFunctionRunner.run(fnDescriptor.functionName, thisArg, [param])
93
+ .then(cb)
94
+ .catch((err) => {
95
+ var logger = req.loggingContext.getLogger(logging.CATEGORY);
96
+ logger.error(wrapAppError(err), format('Execution of OData exit for request "%s%s" failed', self._rootUriPath, req.path));
97
+ cb(err);
98
+ });
99
+ } catch (err) {
100
+ cb(err);
101
+ }
102
+ }
103
+
104
+ var requestOptions = new odata.RequestOptions({
105
+ functionExecutor: odataExitRunner,
106
+ dbOpenCB: retrieveClient,
107
+ locale: locale.dbLocale,
108
+ logger: createTrace({ req: req, location: this._rootUriPath })
109
+ });
110
+
111
+ return { requestOptions: requestOptions, clientWrapper: clientWrapper };
112
+ };
113
+
114
+ ODataService.prototype.clearCache = function(tenant) {
115
+ if (tenant) {
116
+ delete this._handlers[tenant];
117
+ } else {
118
+ this._handlers = {};
119
+ }
120
+ };
121
+
122
+ ODataService.prototype._retrieveDbOptions = function (req, res, cb) {
123
+ var dbReqOptions = this._rt.get('hanaDbOptions').forRequest(req, res.locals.locale);
124
+ dbReqOptions.getInstanceOptions(cb);
125
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var serviceFactory = require('./service-factory');
4
+ var ODataService = require('./ODataService');
5
+
6
+ module.exports.createServices = serviceFactory.createServices;
7
+ module.exports.ODataService = ODataService;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var assert = require('assert');
4
+ var logger = require('../logging').logger;
5
+ var tracer = require('../logging').tracer;
6
+ var ODataService = require('./ODataService');
7
+
8
+ exports.createServices = createServices;
9
+
10
+
11
+ function createServices(rt) {
12
+ assert(rt, 'valid runtime is required');
13
+
14
+ var services = [];
15
+
16
+ for (var pathname in rt.xsodata) {
17
+ try {
18
+ services.push(new ODataService(rt, pathname, rt.xsodata[pathname]));
19
+ tracer.info('Registered OData handler for path: "%s"', pathname);
20
+ } catch (err) {
21
+ logger.error(err, 'Failed to register OData handler for "%s"', pathname);
22
+ }
23
+ }
24
+
25
+ return services;
26
+ }
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ var passport = require('passport-strategy');
4
+ var util = require('util');
5
+
6
+ function Strategy() {
7
+ passport.Strategy.call(this);
8
+ this.name = 'anonymous';
9
+ }
10
+
11
+ util.inherits(Strategy, passport.Strategy);
12
+
13
+ Strategy.prototype.authenticate = function() {
14
+ this.pass();
15
+ };
16
+
17
+ module.exports = Strategy;
package/lib/routes.js ADDED
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ var http = require('http');
4
+ var format = require('util').format;
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+ var xssSecure = require('@sap/xss-secure');
8
+ var logging = require('./logging');
9
+ var wrapAppError = require('./utils/errors/wrap-app-error');
10
+
11
+ var errorPageTemplate = fs.readFileSync(path.join(__dirname, 'views', 'error.html')).toString();
12
+
13
+ exports.xsjs = function (rt) {
14
+ return async function xsjsHandler(req, res, next) {
15
+ var pathToScript = res.locals.pathToScript;
16
+ req.loggingContext.getTracer(__filename).info('Running script "%s"', pathToScript);
17
+ try {
18
+ await rt.runXsjs(pathToScript, req.$);
19
+ req.$.response._pipe(res);
20
+ } catch (err) {
21
+ next(err);
22
+ } finally {
23
+ cleanUp(rt, req);
24
+ }
25
+ };
26
+ };
27
+
28
+ exports.xsodata = function (rt, odataService) {
29
+ return function _odataRouteHandler(req, res, next) {
30
+ var odataPath = odataService.getRootUriPath();
31
+ var tracer = req.loggingContext.getTracer(__filename);
32
+ tracer.info('Starting OData handling for request "%s%s"', odataPath, req.path);
33
+ try {
34
+ odataService.handle(req, res, function (err) {
35
+ rt.triggerGc();
36
+ if (err) {
37
+ return next(err);
38
+ }
39
+ tracer.info('Finished OData handling for request "%s%s"', odataPath, req.path);
40
+ });
41
+ } catch (err) {
42
+ next(err);
43
+ }
44
+ };
45
+ };
46
+
47
+ exports.startJob = function (jobsRt, options) {
48
+ return async function (req, res, next) { // eslint-disable-line no-unused-vars
49
+ var logger = req.loggingContext.getLogger(logging.CATEGORY);
50
+ var tracer = req.loggingContext.getTracer(__filename);
51
+ if (!options.anonymous && options.uaa) {
52
+ var scope = options.uaa.xsappname + '.JOBSCHEDULER';
53
+ if (req.authInfo && !req.authInfo.checkScope(scope)) {
54
+ logger.error('Job "%s" - required scope "%s" is missing', req.path, scope);
55
+
56
+ var auditLog = req.app.get('auditLog');
57
+ if (!auditLog) {
58
+ return res.status(403).end();
59
+ }
60
+
61
+ var message = format('Job "%s", received token does not contain required scope: %s', req.path, scope);
62
+ return auditLog.logSecurityEvent(req, message, 'Technical user', function (err) {
63
+ if (err) {
64
+ return next(err);
65
+ }
66
+ res.status(403).end();
67
+ });
68
+ }
69
+ }
70
+
71
+ tracer.info('Starting job "%s"', req.path);
72
+ try {
73
+ await jobsRt.startJobAsync(req);
74
+ res.status(202).json({ success: true });
75
+ tracer.info('Job "%s" started', req.path);
76
+ } catch (err) {
77
+ logger.error(wrapAppError(err), format('Failed to start job "%s"', req.path));
78
+ res.status(500).json({ error: err.message ? err.message : err });
79
+ }
80
+ };
81
+ };
82
+
83
+ exports.error = function (err, req, res, next) { // eslint-disable-line no-unused-vars
84
+ var status = http.STATUS_CODES[err.status] ? err.status : 500;
85
+ var logger = req.loggingContext.getLogger(logging.CATEGORY);
86
+
87
+ if (status >= 400 && status < 500) {
88
+ logger.info('%s %s returning status %d (%s)', req.method, req.originalUrl, status, err.message);
89
+ } else {
90
+ logger.error(wrapAppError(err), format('%s %s returning status %d', req.method, req.originalUrl, status));
91
+ }
92
+
93
+ var title;
94
+ var stacktrace = '';
95
+ if (process.env.NODE_ENV === 'development') {
96
+ title = status + ' ' + err.message;
97
+ stacktrace = err.stack || '';
98
+ } else {
99
+ // do not reveal internal details to the client
100
+ title = status + ' ' + http.STATUS_CODES[status];
101
+ }
102
+ title = xssSecure.encodeHTML(title);
103
+ stacktrace = xssSecure.encodeHTML(stacktrace);
104
+
105
+ var errorPage = errorPageTemplate.replace(/<%= title %>/g, title);
106
+ errorPage = errorPage.replace('<%= stacktrace %>', stacktrace && ('<pre>' + stacktrace + '</pre>'));
107
+ res.set('Content-Type', 'text/html');
108
+ res.status(status).send(errorPage);
109
+ };
110
+
111
+ function cleanUp(rt, req) {
112
+ rt.cleanupContext(req.$);
113
+ req.$ = undefined;
114
+ rt.triggerGc();
115
+ }