@friggframework/admin-scripts 2.0.0--canary.517.8eaf5df.0 → 2.0.0--canary.517.c197eb5.0
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.
- package/README.md +13 -18
- package/index.js +0 -14
- package/package.json +7 -6
- package/src/application/use-cases/__tests__/delete-schedule-use-case.test.js +1 -1
- package/src/application/use-cases/__tests__/get-effective-schedule-use-case.test.js +1 -1
- package/src/application/use-cases/__tests__/upsert-schedule-use-case.test.js +3 -3
- package/src/application/use-cases/delete-schedule-use-case.js +3 -3
- package/src/application/use-cases/get-effective-schedule-use-case.js +3 -3
- package/src/application/use-cases/upsert-schedule-use-case.js +5 -9
- package/src/infrastructure/__tests__/admin-script-router.test.js +3 -5
- package/src/infrastructure/admin-script-router.js +20 -49
- package/src/infrastructure/bootstrap.js +1 -6
- package/src/builtins/__tests__/integration-health-check.test.js +0 -712
- package/src/builtins/__tests__/oauth-token-refresh.test.js +0 -407
- package/src/builtins/index.js +0 -25
- package/src/builtins/integration-health-check.js +0 -311
- package/src/builtins/oauth-token-refresh.js +0 -255
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
const { AdminScriptBase } = require('../application/admin-script-base');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Integration Health Check Script
|
|
5
|
-
*
|
|
6
|
-
* Checks the health of integrations by verifying:
|
|
7
|
-
* - Credential validity
|
|
8
|
-
* - API connectivity
|
|
9
|
-
* - Configuration integrity
|
|
10
|
-
*/
|
|
11
|
-
class IntegrationHealthCheckScript extends AdminScriptBase {
|
|
12
|
-
static Definition = {
|
|
13
|
-
name: 'integration-health-check',
|
|
14
|
-
version: '1.0.0',
|
|
15
|
-
description: 'Checks health of integrations and reports issues',
|
|
16
|
-
source: 'BUILTIN',
|
|
17
|
-
|
|
18
|
-
inputSchema: {
|
|
19
|
-
type: 'object',
|
|
20
|
-
properties: {
|
|
21
|
-
integrationIds: {
|
|
22
|
-
type: 'array',
|
|
23
|
-
items: { type: 'string' },
|
|
24
|
-
description:
|
|
25
|
-
'Specific integration IDs to check (optional, defaults to all)',
|
|
26
|
-
},
|
|
27
|
-
checkCredentials: {
|
|
28
|
-
type: 'boolean',
|
|
29
|
-
default: true,
|
|
30
|
-
description: 'Verify credential validity',
|
|
31
|
-
},
|
|
32
|
-
checkConnectivity: {
|
|
33
|
-
type: 'boolean',
|
|
34
|
-
default: true,
|
|
35
|
-
description: 'Test API connectivity',
|
|
36
|
-
},
|
|
37
|
-
updateStatus: {
|
|
38
|
-
type: 'boolean',
|
|
39
|
-
default: false,
|
|
40
|
-
description: 'Update integration status based on health',
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
outputSchema: {
|
|
46
|
-
type: 'object',
|
|
47
|
-
properties: {
|
|
48
|
-
healthy: { type: 'number' },
|
|
49
|
-
unhealthy: { type: 'number' },
|
|
50
|
-
unknown: { type: 'number' },
|
|
51
|
-
results: { type: 'array' },
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
config: {
|
|
56
|
-
timeout: 900000, // 15 minutes
|
|
57
|
-
requireIntegrationInstance: true,
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
schedule: {
|
|
61
|
-
enabled: false, // Can be enabled via API
|
|
62
|
-
cronExpression: 'cron(0 6 * * ? *)', // Daily at 6 AM UTC
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
// UI-specific overrides
|
|
66
|
-
display: {
|
|
67
|
-
category: 'maintenance',
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
async execute(params = {}) {
|
|
72
|
-
const {
|
|
73
|
-
integrationIds = null,
|
|
74
|
-
checkCredentials = true,
|
|
75
|
-
checkConnectivity = true,
|
|
76
|
-
updateStatus = false,
|
|
77
|
-
} = params;
|
|
78
|
-
|
|
79
|
-
const summary = {
|
|
80
|
-
healthy: 0,
|
|
81
|
-
unhealthy: 0,
|
|
82
|
-
unknown: 0,
|
|
83
|
-
results: [],
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
this.context.log('info', 'Starting integration health check', {
|
|
87
|
-
checkCredentials,
|
|
88
|
-
checkConnectivity,
|
|
89
|
-
updateStatus,
|
|
90
|
-
specificIds: integrationIds?.length || 'all',
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// Get integrations to check
|
|
94
|
-
let integrations;
|
|
95
|
-
if (integrationIds && integrationIds.length > 0) {
|
|
96
|
-
integrations = await Promise.all(
|
|
97
|
-
integrationIds.map((id) =>
|
|
98
|
-
this.context.integrationRepository
|
|
99
|
-
.findIntegrationById(id)
|
|
100
|
-
.catch(() => null)
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
integrations = integrations.filter(Boolean);
|
|
104
|
-
} else {
|
|
105
|
-
integrations = await this.getAllIntegrations();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
this.context.log(
|
|
109
|
-
'info',
|
|
110
|
-
`Checking ${integrations.length} integrations`
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
for (const integration of integrations) {
|
|
114
|
-
const result = await this.checkIntegration(integration, {
|
|
115
|
-
checkCredentials,
|
|
116
|
-
checkConnectivity,
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
summary.results.push(result);
|
|
120
|
-
|
|
121
|
-
if (result.status === 'healthy') {
|
|
122
|
-
summary.healthy++;
|
|
123
|
-
} else if (result.status === 'unhealthy') {
|
|
124
|
-
summary.unhealthy++;
|
|
125
|
-
} else {
|
|
126
|
-
summary.unknown++;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Optionally update integration status
|
|
130
|
-
if (updateStatus && result.status !== 'unknown') {
|
|
131
|
-
try {
|
|
132
|
-
const newStatus =
|
|
133
|
-
result.status === 'healthy' ? 'ACTIVE' : 'ERROR';
|
|
134
|
-
await this.context.integrationRepository.updateIntegrationStatus(
|
|
135
|
-
integration.id,
|
|
136
|
-
newStatus
|
|
137
|
-
);
|
|
138
|
-
this.context.log(
|
|
139
|
-
'info',
|
|
140
|
-
`Updated status for ${integration.id} to ${newStatus}`
|
|
141
|
-
);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
this.context.log(
|
|
144
|
-
'warn',
|
|
145
|
-
`Failed to update status for ${integration.id}`,
|
|
146
|
-
{
|
|
147
|
-
error: error.message,
|
|
148
|
-
}
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
this.context.log('info', 'Health check completed', {
|
|
155
|
-
healthy: summary.healthy,
|
|
156
|
-
unhealthy: summary.unhealthy,
|
|
157
|
-
unknown: summary.unknown,
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
return summary;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async getAllIntegrations() {
|
|
164
|
-
return this.context.integrationRepository.findIntegrations({});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
async checkIntegration(integration, options) {
|
|
168
|
-
const { checkCredentials, checkConnectivity } = options;
|
|
169
|
-
const result = this._createCheckResult(integration);
|
|
170
|
-
|
|
171
|
-
try {
|
|
172
|
-
await this._runChecks(integration, result, {
|
|
173
|
-
checkCredentials,
|
|
174
|
-
checkConnectivity,
|
|
175
|
-
});
|
|
176
|
-
this._determineOverallStatus(result);
|
|
177
|
-
} catch (error) {
|
|
178
|
-
this._handleCheckError(integration, result, error);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return result;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Create initial check result object
|
|
186
|
-
* @private
|
|
187
|
-
*/
|
|
188
|
-
_createCheckResult(integration) {
|
|
189
|
-
return {
|
|
190
|
-
integrationId: integration.id,
|
|
191
|
-
integrationType: integration.config?.type || 'unknown',
|
|
192
|
-
status: 'unknown',
|
|
193
|
-
checks: {},
|
|
194
|
-
issues: [],
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Run all requested checks
|
|
200
|
-
* @private
|
|
201
|
-
*/
|
|
202
|
-
async _runChecks(integration, result, options) {
|
|
203
|
-
const { checkCredentials, checkConnectivity } = options;
|
|
204
|
-
|
|
205
|
-
if (checkCredentials) {
|
|
206
|
-
this._addCheckResult(
|
|
207
|
-
result,
|
|
208
|
-
'credentials',
|
|
209
|
-
this.checkCredentialValidity(integration)
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (checkConnectivity) {
|
|
214
|
-
this._addCheckResult(
|
|
215
|
-
result,
|
|
216
|
-
'connectivity',
|
|
217
|
-
await this.checkApiConnectivity(integration)
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Add a check result and track any issues
|
|
224
|
-
* @private
|
|
225
|
-
*/
|
|
226
|
-
_addCheckResult(result, checkName, checkResult) {
|
|
227
|
-
result.checks[checkName] = checkResult;
|
|
228
|
-
if (!checkResult.valid) {
|
|
229
|
-
result.issues.push(checkResult.issue);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Determine overall health status from issues
|
|
235
|
-
* @private
|
|
236
|
-
*/
|
|
237
|
-
_determineOverallStatus(result) {
|
|
238
|
-
result.status = result.issues.length === 0 ? 'healthy' : 'unhealthy';
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Handle check error and update result
|
|
243
|
-
* @private
|
|
244
|
-
*/
|
|
245
|
-
_handleCheckError(integration, result, error) {
|
|
246
|
-
this.context.log(
|
|
247
|
-
'error',
|
|
248
|
-
`Error checking integration ${integration.id}`,
|
|
249
|
-
{
|
|
250
|
-
error: error.message,
|
|
251
|
-
}
|
|
252
|
-
);
|
|
253
|
-
result.status = 'unknown';
|
|
254
|
-
result.issues.push(`Check failed: ${error.message}`);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
checkCredentialValidity(integration) {
|
|
258
|
-
const result = { valid: true, issue: null };
|
|
259
|
-
|
|
260
|
-
// Check for access token
|
|
261
|
-
if (!integration.config?.credentials?.access_token) {
|
|
262
|
-
result.valid = false;
|
|
263
|
-
result.issue = 'Missing access token';
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Check for expiry
|
|
268
|
-
const expiresAt = integration.config?.credentials?.expires_at;
|
|
269
|
-
if (expiresAt) {
|
|
270
|
-
const expiryTime = new Date(expiresAt);
|
|
271
|
-
if (expiryTime < new Date()) {
|
|
272
|
-
result.valid = false;
|
|
273
|
-
result.issue = 'Access token expired';
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return result;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
async checkApiConnectivity(integration) {
|
|
282
|
-
const result = { valid: true, issue: null, responseTime: null };
|
|
283
|
-
|
|
284
|
-
try {
|
|
285
|
-
const startTime = Date.now();
|
|
286
|
-
const instance = await this.context.instantiate(integration.id);
|
|
287
|
-
|
|
288
|
-
// Try to make a simple API call
|
|
289
|
-
if (instance.primary?.api?.getAuthenticationInfo) {
|
|
290
|
-
await instance.primary.api.getAuthenticationInfo();
|
|
291
|
-
} else if (instance.primary?.api?.getCurrentUser) {
|
|
292
|
-
await instance.primary.api.getCurrentUser();
|
|
293
|
-
} else {
|
|
294
|
-
// No suitable health check method
|
|
295
|
-
result.valid = true;
|
|
296
|
-
result.issue = null;
|
|
297
|
-
result.note = 'No health check endpoint available';
|
|
298
|
-
return result;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
result.responseTime = Date.now() - startTime;
|
|
302
|
-
} catch (error) {
|
|
303
|
-
result.valid = false;
|
|
304
|
-
result.issue = `API connectivity failed: ${error.message}`;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return result;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
module.exports = { IntegrationHealthCheckScript };
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
const { AdminScriptBase } = require('../application/admin-script-base');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* OAuth Token Refresh Script
|
|
5
|
-
*
|
|
6
|
-
* Refreshes OAuth tokens for integrations that are near expiry.
|
|
7
|
-
* This helps prevent authentication failures due to expired tokens.
|
|
8
|
-
*/
|
|
9
|
-
class OAuthTokenRefreshScript extends AdminScriptBase {
|
|
10
|
-
static Definition = {
|
|
11
|
-
name: 'oauth-token-refresh',
|
|
12
|
-
version: '1.0.0',
|
|
13
|
-
description: 'Refreshes OAuth tokens for integrations near expiry',
|
|
14
|
-
source: 'BUILTIN',
|
|
15
|
-
|
|
16
|
-
inputSchema: {
|
|
17
|
-
type: 'object',
|
|
18
|
-
properties: {
|
|
19
|
-
integrationIds: {
|
|
20
|
-
type: 'array',
|
|
21
|
-
items: { type: 'string' },
|
|
22
|
-
description:
|
|
23
|
-
'Specific integration IDs to refresh (optional, defaults to all)',
|
|
24
|
-
},
|
|
25
|
-
expiryThresholdHours: {
|
|
26
|
-
type: 'number',
|
|
27
|
-
default: 24,
|
|
28
|
-
description:
|
|
29
|
-
'Refresh tokens expiring within this many hours',
|
|
30
|
-
},
|
|
31
|
-
dryRun: {
|
|
32
|
-
type: 'boolean',
|
|
33
|
-
default: false,
|
|
34
|
-
description: 'Preview without making changes',
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
outputSchema: {
|
|
40
|
-
type: 'object',
|
|
41
|
-
properties: {
|
|
42
|
-
refreshed: { type: 'number' },
|
|
43
|
-
failed: { type: 'number' },
|
|
44
|
-
skipped: { type: 'number' },
|
|
45
|
-
details: { type: 'array' },
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
config: {
|
|
50
|
-
timeout: 600000, // 10 minutes
|
|
51
|
-
requireIntegrationInstance: true, // Needs to call external APIs
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
// UI-specific overrides
|
|
55
|
-
display: {
|
|
56
|
-
category: 'maintenance',
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
async execute(params = {}) {
|
|
61
|
-
const {
|
|
62
|
-
integrationIds = null,
|
|
63
|
-
expiryThresholdHours = 24,
|
|
64
|
-
dryRun = false,
|
|
65
|
-
} = params;
|
|
66
|
-
|
|
67
|
-
const results = {
|
|
68
|
-
refreshed: 0,
|
|
69
|
-
failed: 0,
|
|
70
|
-
skipped: 0,
|
|
71
|
-
details: [],
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
this.context.log('info', 'Starting OAuth token refresh', {
|
|
75
|
-
expiryThresholdHours,
|
|
76
|
-
dryRun,
|
|
77
|
-
specificIds: integrationIds?.length || 'all',
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Get integrations to check
|
|
81
|
-
let integrations;
|
|
82
|
-
if (integrationIds && integrationIds.length > 0) {
|
|
83
|
-
integrations = await Promise.all(
|
|
84
|
-
integrationIds.map((id) =>
|
|
85
|
-
this.context.integrationRepository
|
|
86
|
-
.findIntegrationById(id)
|
|
87
|
-
.catch(() => null)
|
|
88
|
-
)
|
|
89
|
-
);
|
|
90
|
-
integrations = integrations.filter(Boolean);
|
|
91
|
-
} else {
|
|
92
|
-
// Get all integrations (this would need to be paginated for large deployments)
|
|
93
|
-
integrations = await this.getAllIntegrations();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
this.context.log(
|
|
97
|
-
'info',
|
|
98
|
-
`Found ${integrations.length} integrations to check`
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
for (const integration of integrations) {
|
|
102
|
-
try {
|
|
103
|
-
const detail = await this.processIntegration(integration, {
|
|
104
|
-
expiryThresholdHours,
|
|
105
|
-
dryRun,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
results.details.push(detail);
|
|
109
|
-
|
|
110
|
-
if (detail.action === 'refreshed') {
|
|
111
|
-
results.refreshed++;
|
|
112
|
-
} else if (detail.action === 'skipped') {
|
|
113
|
-
results.skipped++;
|
|
114
|
-
} else if (detail.action === 'failed') {
|
|
115
|
-
results.failed++;
|
|
116
|
-
}
|
|
117
|
-
} catch (error) {
|
|
118
|
-
this.context.log(
|
|
119
|
-
'error',
|
|
120
|
-
`Error processing integration ${integration.id}`,
|
|
121
|
-
{
|
|
122
|
-
error: error.message,
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
results.failed++;
|
|
126
|
-
results.details.push({
|
|
127
|
-
integrationId: integration.id,
|
|
128
|
-
action: 'failed',
|
|
129
|
-
reason: error.message,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
this.context.log('info', 'OAuth token refresh completed', {
|
|
135
|
-
refreshed: results.refreshed,
|
|
136
|
-
failed: results.failed,
|
|
137
|
-
skipped: results.skipped,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
return results;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async getAllIntegrations() {
|
|
144
|
-
// This is a simplified implementation
|
|
145
|
-
// In production, would need pagination for large datasets
|
|
146
|
-
return this.context.integrationRepository.findIntegrations({});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async processIntegration(integration, options) {
|
|
150
|
-
const { expiryThresholdHours, dryRun } = options;
|
|
151
|
-
|
|
152
|
-
// Check prerequisites
|
|
153
|
-
const skipReason = this._checkRefreshPrerequisites(
|
|
154
|
-
integration,
|
|
155
|
-
expiryThresholdHours
|
|
156
|
-
);
|
|
157
|
-
if (skipReason) {
|
|
158
|
-
return this._createResult(integration.id, 'skipped', skipReason);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Handle dry run
|
|
162
|
-
if (dryRun) {
|
|
163
|
-
this.context.log(
|
|
164
|
-
'info',
|
|
165
|
-
`[DRY RUN] Would refresh token for ${integration.id}`
|
|
166
|
-
);
|
|
167
|
-
return this._createResult(
|
|
168
|
-
integration.id,
|
|
169
|
-
'skipped',
|
|
170
|
-
'Dry run - would have refreshed'
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Perform refresh
|
|
175
|
-
return this._performTokenRefresh(integration);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Check if integration meets prerequisites for token refresh
|
|
180
|
-
* @private
|
|
181
|
-
* @returns {string|null} Skip reason or null if eligible
|
|
182
|
-
*/
|
|
183
|
-
_checkRefreshPrerequisites(integration, expiryThresholdHours) {
|
|
184
|
-
if (!integration.config?.credentials?.access_token) {
|
|
185
|
-
return 'No OAuth credentials found';
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const expiresAt = integration.config?.credentials?.expires_at;
|
|
189
|
-
if (!expiresAt) {
|
|
190
|
-
return 'No expiry time found';
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const expiryTime = new Date(expiresAt);
|
|
194
|
-
const thresholdTime = new Date(
|
|
195
|
-
Date.now() + expiryThresholdHours * 60 * 60 * 1000
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
if (expiryTime > thresholdTime) {
|
|
199
|
-
return 'Token not near expiry';
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return null;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Perform the actual token refresh
|
|
207
|
-
* @private
|
|
208
|
-
*/
|
|
209
|
-
async _performTokenRefresh(integration) {
|
|
210
|
-
const expiresAt = integration.config?.credentials?.expires_at;
|
|
211
|
-
|
|
212
|
-
try {
|
|
213
|
-
const instance = await this.context.instantiate(integration.id);
|
|
214
|
-
|
|
215
|
-
if (!instance.primary?.api?.refreshAccessToken) {
|
|
216
|
-
return this._createResult(
|
|
217
|
-
integration.id,
|
|
218
|
-
'skipped',
|
|
219
|
-
'API does not support token refresh'
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
await instance.primary.api.refreshAccessToken();
|
|
224
|
-
this.context.log(
|
|
225
|
-
'info',
|
|
226
|
-
`Refreshed token for integration ${integration.id}`
|
|
227
|
-
);
|
|
228
|
-
|
|
229
|
-
return {
|
|
230
|
-
integrationId: integration.id,
|
|
231
|
-
action: 'refreshed',
|
|
232
|
-
previousExpiry: expiresAt,
|
|
233
|
-
};
|
|
234
|
-
} catch (error) {
|
|
235
|
-
this.context.log(
|
|
236
|
-
'error',
|
|
237
|
-
`Failed to refresh token for ${integration.id}`,
|
|
238
|
-
{
|
|
239
|
-
error: error.message,
|
|
240
|
-
}
|
|
241
|
-
);
|
|
242
|
-
return this._createResult(integration.id, 'failed', error.message);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Create a result object
|
|
248
|
-
* @private
|
|
249
|
-
*/
|
|
250
|
-
_createResult(integrationId, action, reason) {
|
|
251
|
-
return { integrationId, action, reason };
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
module.exports = { OAuthTokenRefreshScript };
|