MCPcopy Index your code
hub / github.com/simstudioai/sim / authenticateApiKeyFromHeader

Function authenticateApiKeyFromHeader

apps/sim/lib/api-key/service.ts:60–137  ·  view source on GitHub ↗
(
  apiKeyHeader: string,
  options: ApiKeyAuthOptions = {}
)

Source from the content-addressed store, hash-verified

58 * returns `INVALID`.
59 */
60export async function authenticateApiKeyFromHeader(
61 apiKeyHeader: string,
62 options: ApiKeyAuthOptions = {}
63): Promise<ApiKeyAuthResult> {
64 if (!apiKeyHeader) {
65 return { success: false, error: 'API key required' }
66 }
67
68 try {
69 let workspaceSettings: WorkspaceBillingSettings | null = null
70
71 if (options.workspaceId) {
72 workspaceSettings = await getWorkspaceBillingSettings(options.workspaceId)
73 if (!workspaceSettings) {
74 return { success: false, error: 'Workspace not found' }
75 }
76 }
77
78 const keyHash = hashApiKey(apiKeyHeader)
79 const rows: HashCandidate[] = await db
80 .select({
81 id: apiKeyTable.id,
82 userId: apiKeyTable.userId,
83 workspaceId: apiKeyTable.workspaceId,
84 type: apiKeyTable.type,
85 expiresAt: apiKeyTable.expiresAt,
86 userBanned: userTable.banned,
87 })
88 .from(apiKeyTable)
89 .leftJoin(userTable, eq(apiKeyTable.userId, userTable.id))
90 .where(eq(apiKeyTable.keyHash, keyHash))
91
92 if (rows.length === 0) return INVALID
93
94 const record = rows[0]
95 const keyType = record.type as 'personal' | 'workspace'
96
97 // Defense in depth: banning deletes a user's keys, but reject any survivor too.
98 if (record.userBanned) return INVALID
99
100 if (options.userId && record.userId !== options.userId) return INVALID
101 if (options.keyTypes?.length && !options.keyTypes.includes(keyType)) return INVALID
102 if (record.expiresAt && record.expiresAt < new Date()) return INVALID
103
104 if (
105 options.workspaceId &&
106 keyType === 'workspace' &&
107 record.workspaceId !== options.workspaceId
108 ) {
109 return INVALID
110 }
111
112 if (options.workspaceId && keyType === 'personal') {
113 if (!workspaceSettings?.allowPersonalApiKeys) return INVALID
114 if (!record.userId) return INVALID
115
116 const permission = await getUserEntityPermissions(
117 record.userId,

Callers 4

service.test.tsFile · 0.90
checkHybridAuthFunction · 0.90
validateWorkflowAccessFunction · 0.90
authenticateV1RequestFunction · 0.90

Calls 6

hashApiKeyFunction · 0.90
getUserEntityPermissionsFunction · 0.90
debugMethod · 0.80
errorMethod · 0.80
eqFunction · 0.50

Tested by

no test coverage detected