Skip to content

Commit 841091c

Browse files
committed
fix(credentials): address review round 2
Ashby's restricted-key check reads the missing permission from object-shaped error entries too, and a GitLab host that doesn't resolve is reported as not found instead of the provider being unavailable.
1 parent 2217be7 commit 841091c

4 files changed

Lines changed: 42 additions & 2 deletions

File tree

‎apps/sim/lib/credentials/token-service-accounts/validators/gitlab.test.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ describe('GitLab saved token verification', () => {
6262
).rejects.toMatchObject({ code: 'provider_unavailable' })
6363
})
6464

65+
it('reports a host that does not exist as not found, so the user fixes it instead of retrying', async () => {
66+
fetch.mockRejectedValue(
67+
new Error('url hostname could not be resolved', {
68+
cause: Object.assign(new Error('getaddrinfo ENOTFOUND'), { code: 'ENOTFOUND' }),
69+
})
70+
)
71+
72+
await expect(
73+
validateGitLabServiceAccount({ apiToken: 'glpat-x', domain: 'gitlab.exmaple.com' })
74+
).rejects.toMatchObject({ code: 'site_not_found' })
75+
})
76+
6577
it('reports an unreachable GitLab instance as unavailable, not as a bad token', async () => {
6678
fetch.mockResolvedValue(jsonResponse({ message: 'Bad Gateway' }, 502))
6779

‎apps/sim/lib/credentials/token-service-accounts/validators/gitlab.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ export async function validateGitLabServiceAccount(
4848
logUrlValidationDetails: false,
4949
}
5050
)
51-
} catch {
51+
} catch (error) {
52+
// Only ENOTFOUND proves the host doesn't exist; other lookup and network failures may pass.
53+
if ((error as { cause?: { code?: unknown } })?.cause?.code === 'ENOTFOUND') {
54+
throw new TokenServiceAccountValidationError('site_not_found', 400, {
55+
step: 'verify',
56+
reason: 'host does not resolve',
57+
})
58+
}
5259
throw new TokenServiceAccountValidationError('provider_unavailable', 502, {
5360
step: 'verify',
5461
reason: 'could not reach the GitLab host',

‎apps/sim/lib/credentials/token-service-accounts/validators/token-checks.test.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,24 @@ describe('Ashby saved API key verification', () => {
155155
})
156156
})
157157

158+
it('accepts a valid key whose missing permission Ashby names in its errors list', async () => {
159+
vi.stubGlobal(
160+
'fetch',
161+
vi
162+
.fn()
163+
.mockResolvedValue(
164+
jsonResponse(
165+
{ success: false, errors: [{ message: 'missing_endpoint_permission' }] },
166+
403
167+
)
168+
)
169+
)
170+
171+
await expect(validateAshbyServiceAccount({ apiToken: 'scoped' })).resolves.toMatchObject({
172+
displayName: 'Ashby',
173+
})
174+
})
175+
158176
it('rejects a deactivated key Ashby answers with a 403', async () => {
159177
vi.stubGlobal(
160178
'fetch',

‎apps/sim/lib/credentials/token-service-accounts/validators/token-checks.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ export const validateAshbyServiceAccount = tokenCheckValidator({
107107
}),
108108
provesKey: (errorBody) => {
109109
const { errorInfo, errors } = toRecord(errorBody)
110-
return [toRecord(errorInfo).code, ...toArray(errors)].includes('missing_endpoint_permission')
110+
const messages = toArray(errors).map((entry) =>
111+
typeof entry === 'string' ? entry : toRecord(entry).message
112+
)
113+
return [toRecord(errorInfo).code, ...messages].includes('missing_endpoint_permission')
111114
},
112115
})
113116

0 commit comments

Comments
 (0)