@oneuptime/common 7.0.2990 → 7.0.3010

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 (197) hide show
  1. package/Models/AnalyticsModels/ExceptionInstance.ts +488 -0
  2. package/Models/AnalyticsModels/Index.ts +2 -0
  3. package/Models/AnalyticsModels/Span.ts +2 -2
  4. package/Models/DatabaseModels/Index.ts +4 -0
  5. package/Models/DatabaseModels/TelemetryException.ts +978 -0
  6. package/Server/API/StatusAPI.ts +63 -51
  7. package/Server/EnvironmentConfig.ts +3 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1724610006927-MigrationName.ts +93 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1724613666632-MigrationName.ts +60 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1724659071843-MigrationName.ts +17 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  12. package/Server/Infrastructure/Queue.ts +36 -1
  13. package/Server/Infrastructure/QueueWorker.ts +2 -2
  14. package/Server/Services/DatabaseService.ts +4 -5
  15. package/Server/Services/ExceptionInstanceService.ts +11 -0
  16. package/Server/Services/Index.ts +5 -0
  17. package/Server/Services/StatusPageDomainService.ts +118 -59
  18. package/Server/Services/TelemetryExceptionService.ts +10 -0
  19. package/Server/Types/Database/Permissions/Index.ts +1 -1
  20. package/Server/Types/Database/UpdateByID.ts +1 -1
  21. package/Server/Utils/Greenlock/Greenlock.ts +331 -204
  22. package/Server/Utils/Logger.ts +8 -2
  23. package/Server/Utils/Telemetry.ts +109 -25
  24. package/Types/Code/CodeType.ts +1 -0
  25. package/Types/Database/PartialEntity.ts +14 -1
  26. package/Types/Date.ts +9 -1
  27. package/Types/Icon/IconProp.ts +2 -0
  28. package/Types/Permission.ts +39 -0
  29. package/UI/Components/ActionCard/ActionCard.tsx +66 -0
  30. package/UI/Components/Alerts/Alert.tsx +69 -60
  31. package/UI/Components/Card/Card.tsx +1 -0
  32. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +4 -17
  33. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +1005 -0
  34. package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +3 -0
  35. package/UI/Components/Charts/ChartLibrary/Utils/ChartColors.ts +117 -0
  36. package/UI/Components/Charts/ChartLibrary/Utils/Cx.ts +8 -0
  37. package/UI/Components/Charts/ChartLibrary/Utils/GetYAxisDomain.ts +15 -0
  38. package/UI/Components/Charts/ChartLibrary/Utils/HasOnlyOneValueForKey.ts +19 -0
  39. package/UI/Components/Charts/ChartLibrary/Utils/UseWindowOnResize.ts +17 -0
  40. package/UI/Components/Charts/Line/LineChart.tsx +58 -225
  41. package/UI/Components/Charts/Types/ChartCurve.ts +7 -0
  42. package/UI/Components/Charts/Types/DataPoint.ts +7 -0
  43. package/UI/Components/Charts/Types/SeriesPoint.ts +7 -0
  44. package/UI/Components/Charts/Types/SeriesPoints.ts +6 -0
  45. package/UI/Components/Charts/Types/XAxis/XAxis.ts +21 -0
  46. package/UI/Components/Charts/Types/XAxis/XAxisMaxMin.ts +3 -0
  47. package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +26 -0
  48. package/UI/Components/Charts/Types/XAxis/XAxisType.ts +6 -0
  49. package/UI/Components/Charts/Types/XValue.ts +3 -0
  50. package/UI/Components/Charts/Types/YAxis/YAxis.ts +22 -0
  51. package/UI/Components/Charts/Types/YAxis/YAxisMaxMin.ts +3 -0
  52. package/UI/Components/Charts/Types/YAxis/YAxisType.ts +5 -0
  53. package/UI/Components/Charts/Types/YValue.ts +3 -0
  54. package/UI/Components/Charts/Utils/DataPoint.ts +188 -0
  55. package/UI/Components/Charts/Utils/XAxis.ts +267 -0
  56. package/UI/Components/Detail/Detail.tsx +6 -1
  57. package/UI/Components/GanttChart/Row/Row.tsx +4 -2
  58. package/UI/Components/GanttChart/Row/RowLabel.tsx +7 -3
  59. package/UI/Components/Icon/Icon.tsx +16 -0
  60. package/UI/Components/LogsViewer/LogsViewer.tsx +1 -1
  61. package/UI/Components/Types/FieldType.ts +1 -0
  62. package/UI/Config.ts +2 -0
  63. package/UI/Utils/Telemetry.ts +7 -2
  64. package/Utils/Crypto.ts +11 -0
  65. package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +445 -0
  66. package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -0
  67. package/build/dist/Models/AnalyticsModels/Index.js +2 -0
  68. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  69. package/build/dist/Models/AnalyticsModels/Span.js +2 -2
  70. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  71. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  72. package/build/dist/Models/DatabaseModels/TelemetryException.js +1010 -0
  73. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -0
  74. package/build/dist/Server/API/StatusAPI.js +52 -44
  75. package/build/dist/Server/API/StatusAPI.js.map +1 -1
  76. package/build/dist/Server/EnvironmentConfig.js +1 -0
  77. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  78. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1724610006927-MigrationName.js +38 -0
  79. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1724610006927-MigrationName.js.map +1 -0
  80. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1724613666632-MigrationName.js +26 -0
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1724613666632-MigrationName.js.map +1 -0
  82. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1724659071843-MigrationName.js +12 -0
  83. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1724659071843-MigrationName.js.map +1 -0
  84. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  85. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  86. package/build/dist/Server/Infrastructure/Queue.js +20 -1
  87. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  88. package/build/dist/Server/Infrastructure/QueueWorker.js +2 -2
  89. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  90. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  91. package/build/dist/Server/Services/ExceptionInstanceService.js +9 -0
  92. package/build/dist/Server/Services/ExceptionInstanceService.js.map +1 -0
  93. package/build/dist/Server/Services/Index.js +4 -0
  94. package/build/dist/Server/Services/Index.js.map +1 -1
  95. package/build/dist/Server/Services/StatusPageDomainService.js +101 -53
  96. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  97. package/build/dist/Server/Services/TelemetryExceptionService.js +9 -0
  98. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -0
  99. package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
  100. package/build/dist/Server/Utils/Greenlock/Greenlock.js +234 -157
  101. package/build/dist/Server/Utils/Greenlock/Greenlock.js.map +1 -1
  102. package/build/dist/Server/Utils/Logger.js +5 -1
  103. package/build/dist/Server/Utils/Logger.js.map +1 -1
  104. package/build/dist/Server/Utils/Telemetry.js +63 -22
  105. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  106. package/build/dist/Types/Code/CodeType.js +1 -0
  107. package/build/dist/Types/Code/CodeType.js.map +1 -1
  108. package/build/dist/Types/Database/PartialEntity.js +3 -0
  109. package/build/dist/Types/Database/PartialEntity.js.map +1 -1
  110. package/build/dist/Types/Date.js +7 -1
  111. package/build/dist/Types/Date.js.map +1 -1
  112. package/build/dist/Types/Icon/IconProp.js +2 -0
  113. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  114. package/build/dist/Types/Permission.js +33 -0
  115. package/build/dist/Types/Permission.js.map +1 -1
  116. package/build/dist/UI/Components/ActionCard/ActionCard.js +27 -0
  117. package/build/dist/UI/Components/ActionCard/ActionCard.js.map +1 -0
  118. package/build/dist/UI/Components/Alerts/Alert.js +36 -45
  119. package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
  120. package/build/dist/UI/Components/Card/Card.js +1 -1
  121. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  122. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +4 -9
  123. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  124. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +388 -0
  125. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -0
  126. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +2 -0
  127. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -0
  128. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/ChartColors.js +88 -0
  129. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/ChartColors.js.map +1 -0
  130. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/Cx.js +7 -0
  131. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/Cx.js.map +1 -0
  132. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/GetYAxisDomain.js +7 -0
  133. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/GetYAxisDomain.js.map +1 -0
  134. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/HasOnlyOneValueForKey.js +14 -0
  135. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/HasOnlyOneValueForKey.js.map +1 -0
  136. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseWindowOnResize.js +14 -0
  137. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseWindowOnResize.js.map +1 -0
  138. package/build/dist/UI/Components/Charts/Line/LineChart.js +30 -136
  139. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  140. package/build/dist/UI/Components/Charts/Types/ChartCurve.js +8 -0
  141. package/build/dist/UI/Components/Charts/Types/ChartCurve.js.map +1 -0
  142. package/build/dist/UI/Components/Charts/Types/DataPoint.js +2 -0
  143. package/build/dist/UI/Components/Charts/Types/DataPoint.js.map +1 -0
  144. package/build/dist/UI/Components/Charts/Types/SeriesPoint.js +2 -0
  145. package/build/dist/UI/Components/Charts/Types/SeriesPoint.js.map +1 -0
  146. package/build/dist/UI/Components/Charts/Types/SeriesPoints.js +2 -0
  147. package/build/dist/UI/Components/Charts/Types/SeriesPoints.js.map +1 -0
  148. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js +8 -0
  149. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -0
  150. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisMaxMin.js +2 -0
  151. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisMaxMin.js.map +1 -0
  152. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +27 -0
  153. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -0
  154. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisType.js +7 -0
  155. package/build/dist/UI/Components/Charts/Types/XAxis/XAxisType.js.map +1 -0
  156. package/build/dist/UI/Components/Charts/Types/XValue.js +2 -0
  157. package/build/dist/UI/Components/Charts/Types/XValue.js.map +1 -0
  158. package/build/dist/UI/Components/Charts/Types/YAxis/YAxis.js +8 -0
  159. package/build/dist/UI/Components/Charts/Types/YAxis/YAxis.js.map +1 -0
  160. package/build/dist/UI/Components/Charts/Types/YAxis/YAxisMaxMin.js +2 -0
  161. package/build/dist/UI/Components/Charts/Types/YAxis/YAxisMaxMin.js.map +1 -0
  162. package/build/dist/UI/Components/Charts/Types/YAxis/YAxisType.js +6 -0
  163. package/build/dist/UI/Components/Charts/Types/YAxis/YAxisType.js.map +1 -0
  164. package/build/dist/UI/Components/Charts/Types/YValue.js +2 -0
  165. package/build/dist/UI/Components/Charts/Types/YValue.js.map +1 -0
  166. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +109 -0
  167. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -0
  168. package/build/dist/UI/Components/Charts/Utils/XAxis.js +241 -0
  169. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -0
  170. package/build/dist/UI/Components/Detail/Detail.js +5 -1
  171. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  172. package/build/dist/UI/Components/GanttChart/Row/Row.js +2 -2
  173. package/build/dist/UI/Components/GanttChart/Row/Row.js.map +1 -1
  174. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +3 -3
  175. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +1 -1
  176. package/build/dist/UI/Components/Icon/Icon.js +6 -0
  177. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  178. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +1 -1
  179. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  180. package/build/dist/UI/Components/Types/FieldType.js +1 -0
  181. package/build/dist/UI/Components/Types/FieldType.js.map +1 -1
  182. package/build/dist/UI/Config.js +1 -0
  183. package/build/dist/UI/Config.js.map +1 -1
  184. package/build/dist/UI/Utils/Telemetry.js +6 -3
  185. package/build/dist/UI/Utils/Telemetry.js.map +1 -1
  186. package/build/dist/Utils/Crypto.js +10 -0
  187. package/build/dist/Utils/Crypto.js.map +1 -0
  188. package/package.json +15 -13
  189. package/UI/Components/Charts/Bar/Bar.tsx +0 -0
  190. package/UI/Components/Charts/Base/BaseChart.tsx +0 -0
  191. package/UI/Components/Charts/Tooltip/Tooltip.tsx +0 -84
  192. package/build/dist/UI/Components/Charts/Bar/Bar.js +0 -2
  193. package/build/dist/UI/Components/Charts/Bar/Bar.js.map +0 -1
  194. package/build/dist/UI/Components/Charts/Base/BaseChart.js +0 -2
  195. package/build/dist/UI/Components/Charts/Base/BaseChart.js.map +0 -1
  196. package/build/dist/UI/Components/Charts/Tooltip/Tooltip.js +0 -34
  197. package/build/dist/UI/Components/Charts/Tooltip/Tooltip.js.map +0 -1
@@ -17,82 +17,149 @@ import AcmeCertificate from "Common/Models/DatabaseModels/AcmeCertificate";
17
17
  import AcmeChallenge from "Common/Models/DatabaseModels/AcmeChallenge";
18
18
  import acme from "acme-client";
19
19
  import { Challenge } from "acme-client/types/rfc8555";
20
+ import Telemetry, { Span } from "../Telemetry";
20
21
 
21
22
  export default class GreenlockUtil {
22
23
  public static async renewAllCertsWhichAreExpiringSoon(data: {
23
24
  validateCname: (domain: string) => Promise<boolean>;
24
25
  notifyDomainRemoved: (domain: string) => Promise<void>;
25
26
  }): Promise<void> {
26
- logger.debug("Renewing all certificates");
27
-
28
- // get all certificates which are expiring soon
29
-
30
- const certificates: AcmeCertificate[] = await AcmeCertificateService.findBy(
31
- {
32
- query: {
33
- expiresAt: QueryHelper.lessThanEqualTo(
34
- OneUptimeDate.addRemoveDays(
35
- OneUptimeDate.getCurrentDate(),
36
- 40, // 40 days before expiry
37
- ),
38
- ),
39
- },
40
- limit: LIMIT_MAX,
41
- skip: 0,
42
- select: {
43
- domain: true,
44
- },
45
- sort: {
46
- expiresAt: SortOrder.Ascending,
47
- },
48
- props: {
49
- isRoot: true,
50
- },
51
- },
52
- );
53
-
54
- // order certificate for each domain
55
-
56
- for (const certificate of certificates) {
57
- if (!certificate.domain) {
58
- continue;
59
- }
60
-
61
- try {
62
- //validate cname
63
- const isValidCname: boolean = await data.validateCname(
64
- certificate.domain,
65
- );
66
-
67
- if (!isValidCname) {
68
- // if cname is not valid then remove the domain
69
- await GreenlockUtil.removeDomain(certificate.domain);
70
- await data.notifyDomainRemoved(certificate.domain);
71
- } else {
72
- await GreenlockUtil.orderCert({
73
- domain: certificate.domain,
74
- validateCname: data.validateCname,
27
+ return await Telemetry.startActiveSpan<Promise<void>>({
28
+ name: "GreenlockUtil.renewAllCertsWhichAreExpiringSoon",
29
+ fn: async (span: Span): Promise<void> => {
30
+ try {
31
+ logger.debug("Renewing all certificates");
32
+
33
+ // get all certificates which are expiring soon
34
+
35
+ const certificates: AcmeCertificate[] =
36
+ await AcmeCertificateService.findBy({
37
+ query: {
38
+ expiresAt: QueryHelper.lessThanEqualTo(
39
+ OneUptimeDate.addRemoveDays(
40
+ OneUptimeDate.getCurrentDate(),
41
+ 40, // 40 days before expiry
42
+ ),
43
+ ),
44
+ },
45
+ limit: LIMIT_MAX,
46
+ skip: 0,
47
+ select: {
48
+ domain: true,
49
+ },
50
+ sort: {
51
+ expiresAt: SortOrder.Ascending,
52
+ },
53
+ props: {
54
+ isRoot: true,
55
+ },
56
+ });
57
+
58
+ logger.debug(
59
+ `Found ${certificates.length} certificates which are expiring soon`,
60
+ );
61
+
62
+ // order certificate for each domain
63
+
64
+ for (const certificate of certificates) {
65
+ if (!certificate.domain) {
66
+ continue;
67
+ }
68
+
69
+ logger.debug(
70
+ `Renewing certificate for domain: ${certificate.domain}`,
71
+ );
72
+
73
+ try {
74
+ //validate cname
75
+ const isValidCname: boolean = await data.validateCname(
76
+ certificate.domain,
77
+ );
78
+
79
+ if (!isValidCname) {
80
+ logger.debug(
81
+ `CNAME is not valid for domain: ${certificate.domain}`,
82
+ );
83
+
84
+ // if cname is not valid then remove the domain
85
+ await GreenlockUtil.removeDomain(certificate.domain);
86
+ await data.notifyDomainRemoved(certificate.domain);
87
+
88
+ logger.error(
89
+ `Cname is not valid for domain: ${certificate.domain}`,
90
+ );
91
+ } else {
92
+ logger.debug(
93
+ `CNAME is valid for domain: ${certificate.domain}`,
94
+ );
95
+
96
+ await GreenlockUtil.orderCert({
97
+ domain: certificate.domain,
98
+ validateCname: data.validateCname,
99
+ });
100
+
101
+ logger.debug(
102
+ `Certificate renewed for domain: ${certificate.domain}`,
103
+ );
104
+ }
105
+ } catch (e) {
106
+ logger.error(
107
+ `Error renewing certificate for domain: ${certificate.domain}`,
108
+ );
109
+ logger.error(e);
110
+ }
111
+ }
112
+
113
+ Telemetry.endSpan(span);
114
+ } catch (e) {
115
+ logger.error("Error renewing all certificates");
116
+ logger.error(e);
117
+
118
+ // record exception
119
+ Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
120
+ span,
121
+ exception: e,
75
122
  });
123
+
124
+ throw e;
76
125
  }
77
- } catch (e) {
78
- logger.error(
79
- `Error renewing certificate for domain: ${certificate.domain}`,
80
- );
81
- logger.error(e);
82
- }
83
- }
126
+ },
127
+ });
84
128
  }
85
129
 
86
130
  public static async removeDomain(domain: string): Promise<void> {
87
- // remove certificate for this domain.
88
- await AcmeCertificateService.deleteBy({
89
- query: {
90
- domain: domain,
131
+ return await Telemetry.startActiveSpan<Promise<void>>({
132
+ name: "GreenlockUtil.orderCert",
133
+ options: {
134
+ attributes: {
135
+ domain: domain,
136
+ },
91
137
  },
92
- limit: 1,
93
- skip: 0,
94
- props: {
95
- isRoot: true,
138
+ fn: async (span: Span): Promise<void> => {
139
+ try {
140
+ // remove certificate for this domain.
141
+ await AcmeCertificateService.deleteBy({
142
+ query: {
143
+ domain: domain,
144
+ },
145
+ limit: 1,
146
+ skip: 0,
147
+ props: {
148
+ isRoot: true,
149
+ },
150
+ });
151
+
152
+ Telemetry.endSpan(span);
153
+ } catch (err) {
154
+ logger.error(`Error removing domain: ${domain}`);
155
+
156
+ Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
157
+ span,
158
+ exception: err,
159
+ });
160
+
161
+ throw err;
162
+ }
96
163
  },
97
164
  });
98
165
  }
@@ -101,158 +168,218 @@ export default class GreenlockUtil {
101
168
  domain: string;
102
169
  validateCname: (domain: string) => Promise<boolean>;
103
170
  }): Promise<void> {
104
- try {
105
- let { domain } = data;
106
-
107
- domain = domain.trim().toLowerCase();
108
-
109
- const acmeAccountKeyInBase64: string = LetsEncryptAccountKey;
110
-
111
- if (!acmeAccountKeyInBase64) {
112
- throw new ServerException(
113
- "No lets encrypt account key found in environment variables. Please add one.",
114
- );
115
- }
116
-
117
- let acmeAccountKey: string = Buffer.from(
118
- acmeAccountKeyInBase64,
119
- "base64",
120
- ).toString();
121
-
122
- acmeAccountKey = Text.replaceAll(acmeAccountKey, "\\n", "\n");
123
-
124
- //validate cname
125
-
126
- const isValidCname: boolean = await data.validateCname(domain);
127
-
128
- if (!isValidCname) {
129
- await GreenlockUtil.removeDomain(domain);
130
- logger.error(`Cname is not valid for domain: ${domain}`);
131
- throw new BadDataException("Cname is not valid for domain " + domain);
132
- }
133
-
134
- const client: acme.Client = new acme.Client({
135
- directoryUrl: acme.directory.letsencrypt.production,
136
- accountKey: acmeAccountKey,
137
- });
138
-
139
- const [certificateKey, certificateRequest] = await acme.crypto.createCsr({
140
- commonName: domain,
141
- });
142
-
143
- const certificate: string = await client.auto({
144
- csr: certificateRequest,
145
- email: LetsEncryptNotificationEmail.toString(),
146
- termsOfServiceAgreed: true,
147
- challengePriority: ["http-01"], // only http-01 challenge is supported by oneuptime
148
- challengeCreateFn: async (
149
- authz: acme.Authorization,
150
- challenge: Challenge,
151
- keyAuthorization: string,
152
- ) => {
153
- // Satisfy challenge here
154
- /* http-01 */
155
- if (challenge.type === "http-01") {
156
- const acmeChallenge: AcmeChallenge = new AcmeChallenge();
157
- acmeChallenge.challenge = keyAuthorization;
158
- acmeChallenge.token = challenge.token;
159
- acmeChallenge.domain = authz.identifier.value;
160
-
161
- await AcmeChallengeService.create({
162
- data: acmeChallenge,
171
+ return await Telemetry.startActiveSpan<Promise<void>>({
172
+ name: "GreenlockUtil.orderCert",
173
+ options: {
174
+ attributes: {
175
+ domain: data.domain,
176
+ },
177
+ },
178
+ fn: async (span: Span): Promise<void> => {
179
+ try {
180
+ logger.debug(
181
+ `GreenlockUtil - Ordering certificate for domain: ${data.domain}`,
182
+ );
183
+
184
+ let { domain } = data;
185
+
186
+ domain = domain.trim().toLowerCase();
187
+
188
+ const acmeAccountKeyInBase64: string = LetsEncryptAccountKey;
189
+
190
+ if (!acmeAccountKeyInBase64) {
191
+ throw new ServerException(
192
+ "No lets encrypt account key found in environment variables. Please add one.",
193
+ );
194
+ }
195
+
196
+ let acmeAccountKey: string = Buffer.from(
197
+ acmeAccountKeyInBase64,
198
+ "base64",
199
+ ).toString();
200
+
201
+ acmeAccountKey = Text.replaceAll(acmeAccountKey, "\\n", "\n");
202
+
203
+ //validate cname
204
+
205
+ logger.debug(`Validating cname for domain: ${domain}`);
206
+
207
+ const isValidCname: boolean = await data.validateCname(domain);
208
+
209
+ if (!isValidCname) {
210
+ logger.debug(`CNAME is not valid for domain: ${domain}`);
211
+ logger.debug(`Removing domain: ${domain}`);
212
+
213
+ await GreenlockUtil.removeDomain(domain);
214
+ logger.error(`Cname is not valid for domain: ${domain}`);
215
+ throw new BadDataException(
216
+ "Cname is not valid for domain " + domain,
217
+ );
218
+ }
219
+
220
+ logger.debug(`Cname is valid for domain: ${domain}`);
221
+
222
+ const client: acme.Client = new acme.Client({
223
+ directoryUrl: acme.directory.letsencrypt.production,
224
+ accountKey: acmeAccountKey,
225
+ });
226
+
227
+ const [certificateKey, certificateRequest] =
228
+ await acme.crypto.createCsr({
229
+ commonName: domain,
230
+ });
231
+
232
+ logger.debug(`Ordering certificate for domain: ${domain}`);
233
+
234
+ const certificate: string = await client.auto({
235
+ csr: certificateRequest,
236
+ email: LetsEncryptNotificationEmail.toString(),
237
+ termsOfServiceAgreed: true,
238
+ challengePriority: ["http-01"], // only http-01 challenge is supported by oneuptime
239
+ challengeCreateFn: async (
240
+ authz: acme.Authorization,
241
+ challenge: Challenge,
242
+ keyAuthorization: string,
243
+ ) => {
244
+ // Satisfy challenge here
245
+ /* http-01 */
246
+ if (challenge.type === "http-01") {
247
+ logger.debug(
248
+ `Creating challenge for domain: ${authz.identifier.value}`,
249
+ );
250
+
251
+ const acmeChallenge: AcmeChallenge = new AcmeChallenge();
252
+ acmeChallenge.challenge = keyAuthorization;
253
+ acmeChallenge.token = challenge.token;
254
+ acmeChallenge.domain = authz.identifier.value;
255
+
256
+ await AcmeChallengeService.create({
257
+ data: acmeChallenge,
258
+ props: {
259
+ isRoot: true,
260
+ },
261
+ });
262
+
263
+ logger.debug(
264
+ `Challenge created for domain: ${authz.identifier.value}`,
265
+ );
266
+ }
267
+ },
268
+ challengeRemoveFn: async (
269
+ authz: acme.Authorization,
270
+ challenge: Challenge,
271
+ ) => {
272
+ // Clean up challenge here
273
+
274
+ logger.debug(
275
+ `Removing challenge for domain: ${authz.identifier.value}`,
276
+ );
277
+
278
+ if (challenge.type === "http-01") {
279
+ await AcmeChallengeService.deleteBy({
280
+ query: {
281
+ domain: authz.identifier.value,
282
+ },
283
+ limit: 1,
284
+ skip: 0,
285
+ props: {
286
+ isRoot: true,
287
+ },
288
+ });
289
+ }
290
+
291
+ logger.debug(
292
+ `Challenge removed for domain: ${authz.identifier.value}`,
293
+ );
294
+ },
295
+ });
296
+
297
+ logger.debug(`Certificate ordered for domain: ${domain}`);
298
+
299
+ // get expires at date from certificate
300
+ const cert: acme.CertificateInfo =
301
+ acme.crypto.readCertificateInfo(certificate);
302
+ const issuedAt: Date = cert.notBefore;
303
+ const expiresAt: Date = cert.notAfter;
304
+
305
+ logger.debug(`Certificate expires at: ${expiresAt}`);
306
+ logger.debug(`Certificate issued at: ${issuedAt}`);
307
+
308
+ // check if the certificate is already in the database.
309
+ const existingCertificate: AcmeCertificate | null =
310
+ await AcmeCertificateService.findOneBy({
311
+ query: {
312
+ domain: domain,
313
+ },
314
+ select: {
315
+ _id: true,
316
+ },
163
317
  props: {
164
318
  isRoot: true,
165
319
  },
166
320
  });
167
- }
168
- },
169
- challengeRemoveFn: async (
170
- authz: acme.Authorization,
171
- challenge: Challenge,
172
- ) => {
173
- // Clean up challenge here
174
-
175
- if (challenge.type === "http-01") {
176
- await AcmeChallengeService.deleteBy({
321
+
322
+ if (existingCertificate) {
323
+ logger.debug(`Updating certificate for domain: ${domain}`);
324
+
325
+ // update the certificate
326
+ await AcmeCertificateService.updateBy({
177
327
  query: {
178
- domain: authz.identifier.value,
328
+ domain: domain,
179
329
  },
180
330
  limit: 1,
181
331
  skip: 0,
332
+ data: {
333
+ certificate: certificate.toString(),
334
+ certificateKey: certificateKey.toString(),
335
+ issuedAt: issuedAt,
336
+ expiresAt: expiresAt,
337
+ },
338
+ props: {
339
+ isRoot: true,
340
+ },
341
+ });
342
+
343
+ logger.debug(`Certificate updated for domain: ${domain}`);
344
+ } else {
345
+ logger.debug(`Creating certificate for domain: ${domain}`);
346
+ // create the certificate
347
+ const acmeCertificate: AcmeCertificate = new AcmeCertificate();
348
+
349
+ acmeCertificate.domain = domain;
350
+ acmeCertificate.certificate = certificate.toString();
351
+ acmeCertificate.certificateKey = certificateKey.toString();
352
+ acmeCertificate.issuedAt = issuedAt;
353
+ acmeCertificate.expiresAt = expiresAt;
354
+
355
+ await AcmeCertificateService.create({
356
+ data: acmeCertificate,
182
357
  props: {
183
358
  isRoot: true,
184
359
  },
185
360
  });
361
+
362
+ logger.debug(`Certificate created for domain: ${domain}`);
186
363
  }
187
- },
188
- });
189
-
190
- // get expires at date from certificate
191
- const cert: acme.CertificateInfo =
192
- acme.crypto.readCertificateInfo(certificate);
193
- const issuedAt: Date = cert.notBefore;
194
- const expiresAt: Date = cert.notAfter;
195
-
196
- // check if the certificate is already in the database.
197
- const existingCertificate: AcmeCertificate | null =
198
- await AcmeCertificateService.findOneBy({
199
- query: {
200
- domain: domain,
201
- },
202
- select: {
203
- _id: true,
204
- },
205
- props: {
206
- isRoot: true,
207
- },
208
- });
209
-
210
- if (existingCertificate) {
211
- // update the certificate
212
- await AcmeCertificateService.updateBy({
213
- query: {
214
- domain: domain,
215
- },
216
- limit: 1,
217
- skip: 0,
218
- data: {
219
- certificate: certificate.toString(),
220
- certificateKey: certificateKey.toString(),
221
- issuedAt: issuedAt,
222
- expiresAt: expiresAt,
223
- },
224
- props: {
225
- isRoot: true,
226
- },
227
- });
228
- } else {
229
- // create the certificate
230
- const acmeCertificate: AcmeCertificate = new AcmeCertificate();
231
-
232
- acmeCertificate.domain = domain;
233
- acmeCertificate.certificate = certificate.toString();
234
- acmeCertificate.certificateKey = certificateKey.toString();
235
- acmeCertificate.issuedAt = issuedAt;
236
- acmeCertificate.expiresAt = expiresAt;
237
-
238
- await AcmeCertificateService.create({
239
- data: acmeCertificate,
240
- props: {
241
- isRoot: true,
242
- },
243
- });
244
- }
245
- } catch (e) {
246
- logger.error(`Error ordering certificate for domain: ${data.domain}`);
247
- logger.error(e);
248
-
249
- if (e instanceof Exception) {
250
- throw e;
251
- }
252
-
253
- throw new ServerException(
254
- `Unable to order certificate for ${data.domain}. Please contact support at support@oneuptime.com for more information.`,
255
- );
256
- }
364
+
365
+ Telemetry.endSpan(span);
366
+ } catch (e) {
367
+ logger.error(`Error ordering certificate for domain: ${data.domain}`);
368
+
369
+ Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
370
+ span,
371
+ exception: e,
372
+ });
373
+
374
+ if (e instanceof Exception) {
375
+ throw e;
376
+ }
377
+
378
+ throw new ServerException(
379
+ `Unable to order certificate for ${data.domain}. Please contact support at support@oneuptime.com for more information.`,
380
+ );
381
+ }
382
+ },
383
+ });
257
384
  }
258
385
  }
@@ -1,5 +1,5 @@
1
1
  import { ConfigLogLevel, LogLevel } from "../EnvironmentConfig";
2
- import OneUptimeTelemetry from "./Telemetry";
2
+ import OneUptimeTelemetry, { TelemetryLogger } from "./Telemetry";
3
3
  import { SeverityNumber } from "@opentelemetry/api-logs";
4
4
  import Exception from "Common/Types/Exception/Exception";
5
5
  import { JSONObject } from "Common/Types/JSON";
@@ -93,7 +93,13 @@ export default class logger {
93
93
  body: LogBody;
94
94
  severityNumber: SeverityNumber;
95
95
  }): void {
96
- OneUptimeTelemetry.getLogger().emit({
96
+ const logger: TelemetryLogger | null = OneUptimeTelemetry.getLogger();
97
+
98
+ if (logger === null) {
99
+ return;
100
+ }
101
+
102
+ logger.emit({
97
103
  body: this.serializeLogBody(data.body),
98
104
  severityNumber: data.severityNumber,
99
105
  });