session.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. Object.defineProperty(exports, '__esModule', { value: true });
  2. const utils = require('@sentry/utils');
  3. /**
  4. * Creates a new `Session` object by setting certain default parameters. If optional @param context
  5. * is passed, the passed properties are applied to the session object.
  6. *
  7. * @param context (optional) additional properties to be applied to the returned session object
  8. *
  9. * @returns a new `Session` object
  10. */
  11. function makeSession(context) {
  12. // Both timestamp and started are in seconds since the UNIX epoch.
  13. const startingTime = utils.timestampInSeconds();
  14. const session = {
  15. sid: utils.uuid4(),
  16. init: true,
  17. timestamp: startingTime,
  18. started: startingTime,
  19. duration: 0,
  20. status: 'ok',
  21. errors: 0,
  22. ignoreDuration: false,
  23. toJSON: () => sessionToJSON(session),
  24. };
  25. if (context) {
  26. updateSession(session, context);
  27. }
  28. return session;
  29. }
  30. /**
  31. * Updates a session object with the properties passed in the context.
  32. *
  33. * Note that this function mutates the passed object and returns void.
  34. * (Had to do this instead of returning a new and updated session because closing and sending a session
  35. * makes an update to the session after it was passed to the sending logic.
  36. * @see BaseClient.captureSession )
  37. *
  38. * @param session the `Session` to update
  39. * @param context the `SessionContext` holding the properties that should be updated in @param session
  40. */
  41. // eslint-disable-next-line complexity
  42. function updateSession(session, context = {}) {
  43. if (context.user) {
  44. if (!session.ipAddress && context.user.ip_address) {
  45. session.ipAddress = context.user.ip_address;
  46. }
  47. if (!session.did && !context.did) {
  48. session.did = context.user.id || context.user.email || context.user.username;
  49. }
  50. }
  51. session.timestamp = context.timestamp || utils.timestampInSeconds();
  52. if (context.abnormal_mechanism) {
  53. session.abnormal_mechanism = context.abnormal_mechanism;
  54. }
  55. if (context.ignoreDuration) {
  56. session.ignoreDuration = context.ignoreDuration;
  57. }
  58. if (context.sid) {
  59. // Good enough uuid validation. — Kamil
  60. session.sid = context.sid.length === 32 ? context.sid : utils.uuid4();
  61. }
  62. if (context.init !== undefined) {
  63. session.init = context.init;
  64. }
  65. if (!session.did && context.did) {
  66. session.did = `${context.did}`;
  67. }
  68. if (typeof context.started === 'number') {
  69. session.started = context.started;
  70. }
  71. if (session.ignoreDuration) {
  72. session.duration = undefined;
  73. } else if (typeof context.duration === 'number') {
  74. session.duration = context.duration;
  75. } else {
  76. const duration = session.timestamp - session.started;
  77. session.duration = duration >= 0 ? duration : 0;
  78. }
  79. if (context.release) {
  80. session.release = context.release;
  81. }
  82. if (context.environment) {
  83. session.environment = context.environment;
  84. }
  85. if (!session.ipAddress && context.ipAddress) {
  86. session.ipAddress = context.ipAddress;
  87. }
  88. if (!session.userAgent && context.userAgent) {
  89. session.userAgent = context.userAgent;
  90. }
  91. if (typeof context.errors === 'number') {
  92. session.errors = context.errors;
  93. }
  94. if (context.status) {
  95. session.status = context.status;
  96. }
  97. }
  98. /**
  99. * Closes a session by setting its status and updating the session object with it.
  100. * Internally calls `updateSession` to update the passed session object.
  101. *
  102. * Note that this function mutates the passed session (@see updateSession for explanation).
  103. *
  104. * @param session the `Session` object to be closed
  105. * @param status the `SessionStatus` with which the session was closed. If you don't pass a status,
  106. * this function will keep the previously set status, unless it was `'ok'` in which case
  107. * it is changed to `'exited'`.
  108. */
  109. function closeSession(session, status) {
  110. let context = {};
  111. if (status) {
  112. context = { status };
  113. } else if (session.status === 'ok') {
  114. context = { status: 'exited' };
  115. }
  116. updateSession(session, context);
  117. }
  118. /**
  119. * Serializes a passed session object to a JSON object with a slightly different structure.
  120. * This is necessary because the Sentry backend requires a slightly different schema of a session
  121. * than the one the JS SDKs use internally.
  122. *
  123. * @param session the session to be converted
  124. *
  125. * @returns a JSON object of the passed session
  126. */
  127. function sessionToJSON(session) {
  128. return utils.dropUndefinedKeys({
  129. sid: `${session.sid}`,
  130. init: session.init,
  131. // Make sure that sec is converted to ms for date constructor
  132. started: new Date(session.started * 1000).toISOString(),
  133. timestamp: new Date(session.timestamp * 1000).toISOString(),
  134. status: session.status,
  135. errors: session.errors,
  136. did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined,
  137. duration: session.duration,
  138. abnormal_mechanism: session.abnormal_mechanism,
  139. attrs: {
  140. release: session.release,
  141. environment: session.environment,
  142. ip_address: session.ipAddress,
  143. user_agent: session.userAgent,
  144. },
  145. });
  146. }
  147. exports.closeSession = closeSession;
  148. exports.makeSession = makeSession;
  149. exports.updateSession = updateSession;
  150. //# sourceMappingURL=session.js.map