agentlang 0.0.2

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 (240) hide show
  1. package/LICENSE +83 -0
  2. package/README.md +120 -0
  3. package/bin/cli.js +4 -0
  4. package/out/api/http.d.ts +3 -0
  5. package/out/api/http.d.ts.map +1 -0
  6. package/out/api/http.js +290 -0
  7. package/out/api/http.js.map +1 -0
  8. package/out/cli/cli-util.d.ts +7 -0
  9. package/out/cli/cli-util.d.ts.map +1 -0
  10. package/out/cli/cli-util.js +9 -0
  11. package/out/cli/cli-util.js.map +1 -0
  12. package/out/cli/docs.d.ts +2 -0
  13. package/out/cli/docs.d.ts.map +1 -0
  14. package/out/cli/docs.js +236 -0
  15. package/out/cli/docs.js.map +1 -0
  16. package/out/cli/main.d.ts +288 -0
  17. package/out/cli/main.d.ts.map +1 -0
  18. package/out/cli/main.js +119 -0
  19. package/out/cli/main.js.map +1 -0
  20. package/out/cli/openapi-docs.yml +695 -0
  21. package/out/extension/main.cjs +18093 -0
  22. package/out/extension/main.cjs.map +7 -0
  23. package/out/extension/main.d.ts +4 -0
  24. package/out/extension/main.d.ts.map +1 -0
  25. package/out/extension/main.js +42 -0
  26. package/out/extension/main.js.map +1 -0
  27. package/out/language/agentlang-module.d.ts +42 -0
  28. package/out/language/agentlang-module.d.ts.map +1 -0
  29. package/out/language/agentlang-module.js +42 -0
  30. package/out/language/agentlang-module.js.map +1 -0
  31. package/out/language/agentlang-validator.d.ts +15 -0
  32. package/out/language/agentlang-validator.d.ts.map +1 -0
  33. package/out/language/agentlang-validator.js +50 -0
  34. package/out/language/agentlang-validator.js.map +1 -0
  35. package/out/language/generated/ast.d.ts +491 -0
  36. package/out/language/generated/ast.d.ts.map +1 -0
  37. package/out/language/generated/ast.js +934 -0
  38. package/out/language/generated/ast.js.map +1 -0
  39. package/out/language/generated/grammar.d.ts +7 -0
  40. package/out/language/generated/grammar.d.ts.map +1 -0
  41. package/out/language/generated/grammar.js +4475 -0
  42. package/out/language/generated/grammar.js.map +1 -0
  43. package/out/language/generated/module.d.ts +14 -0
  44. package/out/language/generated/module.d.ts.map +1 -0
  45. package/out/language/generated/module.js +21 -0
  46. package/out/language/generated/module.js.map +1 -0
  47. package/out/language/main-browser.d.ts +2 -0
  48. package/out/language/main-browser.d.ts.map +1 -0
  49. package/out/language/main-browser.js +10 -0
  50. package/out/language/main-browser.js.map +1 -0
  51. package/out/language/main.cjs +36229 -0
  52. package/out/language/main.cjs.map +7 -0
  53. package/out/language/main.d.ts +2 -0
  54. package/out/language/main.d.ts.map +1 -0
  55. package/out/language/main.js +11 -0
  56. package/out/language/main.js.map +1 -0
  57. package/out/language/parser.d.ts +9 -0
  58. package/out/language/parser.d.ts.map +1 -0
  59. package/out/language/parser.js +273 -0
  60. package/out/language/parser.js.map +1 -0
  61. package/out/language/syntax.d.ts +155 -0
  62. package/out/language/syntax.d.ts.map +1 -0
  63. package/out/language/syntax.js +527 -0
  64. package/out/language/syntax.js.map +1 -0
  65. package/out/runtime/agents/common.d.ts +2 -0
  66. package/out/runtime/agents/common.d.ts.map +1 -0
  67. package/out/runtime/agents/common.js +178 -0
  68. package/out/runtime/agents/common.js.map +1 -0
  69. package/out/runtime/agents/impl/openai.d.ts +8 -0
  70. package/out/runtime/agents/impl/openai.d.ts.map +1 -0
  71. package/out/runtime/agents/impl/openai.js +15 -0
  72. package/out/runtime/agents/impl/openai.js.map +1 -0
  73. package/out/runtime/agents/provider.d.ts +21 -0
  74. package/out/runtime/agents/provider.d.ts.map +1 -0
  75. package/out/runtime/agents/provider.js +32 -0
  76. package/out/runtime/agents/provider.js.map +1 -0
  77. package/out/runtime/agents/registry.d.ts +2 -0
  78. package/out/runtime/agents/registry.d.ts.map +1 -0
  79. package/out/runtime/agents/registry.js +10 -0
  80. package/out/runtime/agents/registry.js.map +1 -0
  81. package/out/runtime/auth/cognito.d.ts +16 -0
  82. package/out/runtime/auth/cognito.d.ts.map +1 -0
  83. package/out/runtime/auth/cognito.js +186 -0
  84. package/out/runtime/auth/cognito.js.map +1 -0
  85. package/out/runtime/auth/defs.d.ts +11 -0
  86. package/out/runtime/auth/defs.d.ts.map +1 -0
  87. package/out/runtime/auth/defs.js +24 -0
  88. package/out/runtime/auth/defs.js.map +1 -0
  89. package/out/runtime/auth/interface.d.ts +22 -0
  90. package/out/runtime/auth/interface.d.ts.map +1 -0
  91. package/out/runtime/auth/interface.js +2 -0
  92. package/out/runtime/auth/interface.js.map +1 -0
  93. package/out/runtime/defs.js +24 -0
  94. package/out/runtime/defs.js.map +1 -0
  95. package/out/runtime/interpreter.d.ts +69 -0
  96. package/out/runtime/interpreter.d.ts.map +1 -0
  97. package/out/runtime/interpreter.js +1163 -0
  98. package/out/runtime/interpreter.js.map +1 -0
  99. package/out/runtime/loader.d.ts +25 -0
  100. package/out/runtime/loader.d.ts.map +1 -0
  101. package/out/runtime/loader.js +346 -0
  102. package/out/runtime/loader.js.map +1 -0
  103. package/out/runtime/logger.d.ts +2 -0
  104. package/out/runtime/logger.d.ts.map +1 -0
  105. package/out/runtime/logger.js +44 -0
  106. package/out/runtime/logger.js.map +1 -0
  107. package/out/runtime/module.d.ts +273 -0
  108. package/out/runtime/module.d.ts.map +1 -0
  109. package/out/runtime/module.js +1786 -0
  110. package/out/runtime/module.js.map +1 -0
  111. package/out/runtime/modules/ai.d.ts +26 -0
  112. package/out/runtime/modules/ai.d.ts.map +1 -0
  113. package/out/runtime/modules/ai.js +211 -0
  114. package/out/runtime/modules/ai.js.map +1 -0
  115. package/out/runtime/modules/auth.d.ts +39 -0
  116. package/out/runtime/modules/auth.d.ts.map +1 -0
  117. package/out/runtime/modules/auth.js +359 -0
  118. package/out/runtime/modules/auth.js.map +1 -0
  119. package/out/runtime/modules/core.d.ts +2 -0
  120. package/out/runtime/modules/core.d.ts.map +1 -0
  121. package/out/runtime/modules/core.js +67 -0
  122. package/out/runtime/modules/core.js.map +1 -0
  123. package/out/runtime/relgraph.d.ts +21 -0
  124. package/out/runtime/relgraph.d.ts.map +1 -0
  125. package/out/runtime/relgraph.js +156 -0
  126. package/out/runtime/relgraph.js.map +1 -0
  127. package/out/runtime/resolvers/interface.d.ts +59 -0
  128. package/out/runtime/resolvers/interface.d.ts.map +1 -0
  129. package/out/runtime/resolvers/interface.js +111 -0
  130. package/out/runtime/resolvers/interface.js.map +1 -0
  131. package/out/runtime/resolvers/registry.d.ts +8 -0
  132. package/out/runtime/resolvers/registry.d.ts.map +1 -0
  133. package/out/runtime/resolvers/registry.js +26 -0
  134. package/out/runtime/resolvers/registry.js.map +1 -0
  135. package/out/runtime/resolvers/sqldb/database.d.ts +50 -0
  136. package/out/runtime/resolvers/sqldb/database.d.ts.map +1 -0
  137. package/out/runtime/resolvers/sqldb/database.js +618 -0
  138. package/out/runtime/resolvers/sqldb/database.js.map +1 -0
  139. package/out/runtime/resolvers/sqldb/dbutil.d.ts +18 -0
  140. package/out/runtime/resolvers/sqldb/dbutil.d.ts.map +1 -0
  141. package/out/runtime/resolvers/sqldb/dbutil.js +221 -0
  142. package/out/runtime/resolvers/sqldb/dbutil.js.map +1 -0
  143. package/out/runtime/resolvers/sqldb/impl.d.ts +26 -0
  144. package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -0
  145. package/out/runtime/resolvers/sqldb/impl.js +300 -0
  146. package/out/runtime/resolvers/sqldb/impl.js.map +1 -0
  147. package/out/runtime/state.js +83 -0
  148. package/out/runtime/state.js.map +1 -0
  149. package/out/runtime/util.d.ts +43 -0
  150. package/out/runtime/util.d.ts.map +1 -0
  151. package/out/runtime/util.js +447 -0
  152. package/out/runtime/util.js.map +1 -0
  153. package/out/setupClassic.d.ts +98 -0
  154. package/out/setupClassic.d.ts.map +1 -0
  155. package/out/setupClassic.js +38 -0
  156. package/out/setupClassic.js.map +1 -0
  157. package/out/setupCommon.d.ts +2 -0
  158. package/out/setupCommon.d.ts.map +1 -0
  159. package/out/setupCommon.js +33 -0
  160. package/out/setupCommon.js.map +1 -0
  161. package/out/setupExtended.d.ts +40 -0
  162. package/out/setupExtended.d.ts.map +1 -0
  163. package/out/setupExtended.js +67 -0
  164. package/out/setupExtended.js.map +1 -0
  165. package/out/syntaxes/agentlang.monarch.d.ts +77 -0
  166. package/out/syntaxes/agentlang.monarch.d.ts.map +1 -0
  167. package/out/syntaxes/agentlang.monarch.js +31 -0
  168. package/out/syntaxes/agentlang.monarch.js.map +1 -0
  169. package/out/utils/fs/index.d.ts +14 -0
  170. package/out/utils/fs/index.d.ts.map +1 -0
  171. package/out/utils/fs/index.js +26 -0
  172. package/out/utils/fs/index.js.map +1 -0
  173. package/out/utils/fs/interfaces.d.ts +105 -0
  174. package/out/utils/fs/interfaces.d.ts.map +1 -0
  175. package/out/utils/fs/interfaces.js +5 -0
  176. package/out/utils/fs/interfaces.js.map +1 -0
  177. package/out/utils/fs/lightning-fs.d.ts +116 -0
  178. package/out/utils/fs/lightning-fs.d.ts.map +1 -0
  179. package/out/utils/fs/lightning-fs.js +243 -0
  180. package/out/utils/fs/lightning-fs.js.map +1 -0
  181. package/out/utils/fs/node-fs.d.ts +93 -0
  182. package/out/utils/fs/node-fs.d.ts.map +1 -0
  183. package/out/utils/fs/node-fs.js +169 -0
  184. package/out/utils/fs/node-fs.js.map +1 -0
  185. package/out/utils/fs-utils.d.ts +153 -0
  186. package/out/utils/fs-utils.d.ts.map +1 -0
  187. package/out/utils/fs-utils.js +271 -0
  188. package/out/utils/fs-utils.js.map +1 -0
  189. package/out/utils/runtime.d.ts +36 -0
  190. package/out/utils/runtime.d.ts.map +1 -0
  191. package/out/utils/runtime.js +39 -0
  192. package/out/utils/runtime.js.map +1 -0
  193. package/package.json +155 -0
  194. package/src/api/http.ts +361 -0
  195. package/src/cli/cli-util.ts +18 -0
  196. package/src/cli/main.ts +146 -0
  197. package/src/extension/main.ts +51 -0
  198. package/src/language/agentlang-module.ts +75 -0
  199. package/src/language/agentlang-validator.ts +60 -0
  200. package/src/language/agentlang.langium +178 -0
  201. package/src/language/generated/ast.ts +1698 -0
  202. package/src/language/generated/grammar.ts +4477 -0
  203. package/src/language/generated/module.ts +25 -0
  204. package/src/language/main-browser.ts +19 -0
  205. package/src/language/main.ts +13 -0
  206. package/src/language/parser.ts +329 -0
  207. package/src/language/syntax.ts +646 -0
  208. package/src/runtime/agents/common.ts +177 -0
  209. package/src/runtime/agents/impl/openai.ts +19 -0
  210. package/src/runtime/agents/provider.ts +58 -0
  211. package/src/runtime/agents/registry.ts +9 -0
  212. package/src/runtime/auth/cognito.ts +225 -0
  213. package/src/runtime/auth/defs.ts +33 -0
  214. package/src/runtime/auth/interface.ts +31 -0
  215. package/src/runtime/defs.ts +33 -0
  216. package/src/runtime/interpreter.ts +1352 -0
  217. package/src/runtime/loader.ts +450 -0
  218. package/src/runtime/logger.ts +51 -0
  219. package/src/runtime/module.ts +2188 -0
  220. package/src/runtime/modules/ai.ts +257 -0
  221. package/src/runtime/modules/auth.ts +489 -0
  222. package/src/runtime/modules/core.ts +95 -0
  223. package/src/runtime/relgraph.ts +195 -0
  224. package/src/runtime/resolvers/interface.ts +160 -0
  225. package/src/runtime/resolvers/registry.ts +30 -0
  226. package/src/runtime/resolvers/sqldb/database.ts +823 -0
  227. package/src/runtime/resolvers/sqldb/dbutil.ts +257 -0
  228. package/src/runtime/resolvers/sqldb/impl.ts +471 -0
  229. package/src/runtime/state.ts +87 -0
  230. package/src/runtime/util.ts +513 -0
  231. package/src/setupClassic.ts +43 -0
  232. package/src/setupCommon.ts +33 -0
  233. package/src/setupExtended.ts +79 -0
  234. package/src/syntaxes/agentlang.monarch.ts +31 -0
  235. package/src/utils/fs/index.ts +28 -0
  236. package/src/utils/fs/interfaces.ts +118 -0
  237. package/src/utils/fs/lightning-fs.ts +284 -0
  238. package/src/utils/fs/node-fs.ts +185 -0
  239. package/src/utils/fs-utils.ts +304 -0
  240. package/src/utils/runtime.ts +43 -0
@@ -0,0 +1,489 @@
1
+ import { Result, Environment, makeEventEvaluator } from '../interpreter.js';
2
+ import { logger } from '../logger.js';
3
+ import { Instance, RbacPermissionFlag } from '../module.js';
4
+ import { makeCoreModuleName } from '../util.js';
5
+ import { isSqlTrue } from '../resolvers/sqldb/dbutil.js';
6
+ import { AgentlangAuth, SessionInfo, UserInfo } from '../auth/interface.js';
7
+ import { ActiveSessionInfo, AdminUserId, BypassSession, isAuthEnabled } from '../auth/defs.js';
8
+ import { isNodeEnv } from '../../utils/runtime.js';
9
+ import { CognitoAuth } from '../auth/cognito.js';
10
+
11
+ export const CoreAuthModuleName = makeCoreModuleName('auth');
12
+
13
+ export default `module ${CoreAuthModuleName}
14
+
15
+ import "./modules/auth.js" as Auth
16
+
17
+ entity User {
18
+ id UUID @id @default(uuid()),
19
+ email Email @unique @indexed,
20
+ firstName String,
21
+ lastName String
22
+ }
23
+
24
+ workflow CreateUser {
25
+ {User {id CreateUser.id,
26
+ email CreateUser.email,
27
+ firstName CreateUser.firstName,
28
+ lastName CreateUser.lastName}}
29
+ }
30
+
31
+ workflow FindUser {
32
+ {User {id? FindUser.id}} as [user];
33
+ user
34
+ }
35
+
36
+ workflow FindUserByEmail {
37
+ {User {email? FindUserByEmail.email}} as [user];
38
+ user
39
+ }
40
+
41
+ entity Role {
42
+ name String @id
43
+ }
44
+
45
+ relationship UserRole between (User, Role)
46
+
47
+ entity Permission {
48
+ id String @id,
49
+ resourceFqName String @indexed,
50
+ c Boolean,
51
+ r Boolean,
52
+ u Boolean,
53
+ d Boolean
54
+ }
55
+
56
+ relationship RolePermission between(Role, Permission)
57
+
58
+ workflow CreateRole {
59
+ upsert {Role {name CreateRole.name}}
60
+ }
61
+
62
+ workflow FindRole {
63
+ {Role {name? FindRole.name}} as [role];
64
+ role
65
+ }
66
+
67
+ workflow AssignUserToRole {
68
+ {User {id? AssignUserToRole.userId}} as [user];
69
+ {Role {name? AssignUserToRole.roleName}} as [role];
70
+ upsert {UserRole {User user, Role role}}
71
+ }
72
+
73
+ workflow AssignUserToRoleByEmail {
74
+ {User {email? AssignUserToRoleByEmail.email}} as [user];
75
+ {Role {name? AssignUserToRoleByEmail.roleName}} as [role];
76
+ upsert {UserRole {User user, Role role}}
77
+ }
78
+
79
+ workflow FindUserRoles {
80
+ {User {id? FindUserRoles.userId},
81
+ UserRole {Role? {}}}
82
+ }
83
+
84
+ workflow CreatePermission {
85
+ upsert {Permission {id CreatePermission.id,
86
+ resourceFqName CreatePermission.resourceFqName,
87
+ c CreatePermission.c,
88
+ r CreatePermission.r,
89
+ u CreatePermission.u,
90
+ d CreatePermission.d},
91
+ RolePermission {Role {name? CreatePermission.roleName}}}
92
+ }
93
+
94
+ workflow AddPermissionToRole {
95
+ {Role {name? AddPermissionToRole.roleName}} as role;
96
+ {Permission {id? AddPermissionToRole.permissionId}} as perm;
97
+ upsert {RolePermission {Role role, Permission perm}}
98
+ }
99
+
100
+ workflow FindRolePermissions {
101
+ {Role {name? FindRolePermissions.role},
102
+ RolePermission {Permission? {}}}
103
+ }
104
+
105
+ entity Session {
106
+ id UUID @id,
107
+ userId UUID @indexed,
108
+ authToken String @optional,
109
+ isActive Boolean
110
+ }
111
+
112
+ workflow CreateSession {
113
+ {Session {id CreateSession.id, userId CreateSession.userId,
114
+ authToken CreateSession.authToken, isActive true}}
115
+ }
116
+
117
+ workflow FindSession {
118
+ {Session {id? FindSession.id}} as [session];
119
+ session
120
+ }
121
+
122
+ workflow FindUserSession {
123
+ {Session {userId? FindUserSession.id}} as [session];
124
+ session
125
+ }
126
+
127
+ workflow RemoveSession {
128
+ purge {Session {id? RemoveSession.id}}
129
+ }
130
+
131
+ workflow signup {
132
+ await Auth.signUpUser(signup.email, signup.password, signup.userData)
133
+ }
134
+
135
+ workflow login {
136
+ await Auth.loginUser(login.email, login.password)
137
+ }
138
+ `;
139
+
140
+ const evalEvent = makeEventEvaluator(CoreAuthModuleName);
141
+
142
+ export async function createUser(
143
+ id: string,
144
+ email: string,
145
+ firstName: string,
146
+ lastName: string,
147
+ env: Environment
148
+ ): Promise<Result> {
149
+ return await evalEvent(
150
+ 'CreateUser',
151
+ {
152
+ id: id,
153
+ email: email,
154
+ firstName: firstName,
155
+ lastName: lastName,
156
+ },
157
+ env
158
+ );
159
+ }
160
+
161
+ export async function findUser(id: string, env: Environment): Promise<Result> {
162
+ return await evalEvent(
163
+ 'FindUser',
164
+ {
165
+ id: id,
166
+ },
167
+ env
168
+ );
169
+ }
170
+
171
+ export async function findUserByEmail(email: string, env: Environment): Promise<Result> {
172
+ return await evalEvent(
173
+ 'FindUserByEmail',
174
+ {
175
+ email: email,
176
+ },
177
+ env
178
+ );
179
+ }
180
+
181
+ export async function ensureUser(
182
+ email: string,
183
+ firstName: string,
184
+ lastName: string,
185
+ env: Environment
186
+ ) {
187
+ const user = await findUserByEmail(email, env);
188
+ if (user) {
189
+ return user;
190
+ }
191
+ return await createUser(crypto.randomUUID(), email, firstName, lastName, env);
192
+ }
193
+
194
+ export async function ensureUserSession(userId: string, token: string, env: Environment) {
195
+ const sess: Instance = await findUserSession(userId, env);
196
+ if (sess) {
197
+ await removeSession(sess.lookup('id'), env);
198
+ }
199
+ return await createSession(crypto.randomUUID(), userId, token, env);
200
+ }
201
+
202
+ export async function createSession(
203
+ id: string,
204
+ userId: string,
205
+ token: string,
206
+ env: Environment
207
+ ): Promise<Result> {
208
+ return await evalEvent(
209
+ 'CreateSession',
210
+ {
211
+ id: id,
212
+ userId: userId,
213
+ authToken: token,
214
+ },
215
+ env
216
+ );
217
+ }
218
+
219
+ export async function findSession(id: string, env: Environment): Promise<Result> {
220
+ return await evalEvent(
221
+ 'FindSession',
222
+ {
223
+ id: id,
224
+ },
225
+ env
226
+ );
227
+ }
228
+
229
+ export async function findUserSession(userId: string, env: Environment): Promise<Result> {
230
+ return await evalEvent(
231
+ 'FindUserSession',
232
+ {
233
+ userId: userId,
234
+ },
235
+ env
236
+ );
237
+ }
238
+
239
+ export async function removeSession(id: string, env: Environment): Promise<Result> {
240
+ return await evalEvent(
241
+ 'RemoveSession',
242
+ {
243
+ id: id,
244
+ },
245
+ env
246
+ );
247
+ }
248
+
249
+ export async function findRole(name: string, env: Environment): Promise<Result> {
250
+ return await evalEvent('FindRole', { name: name }, env);
251
+ }
252
+
253
+ export async function createRole(name: string, env: Environment) {
254
+ await evalEvent('CreateRole', { name: name }, env).catch((reason: any) => {
255
+ logger.error(`Failed to create role '${name}' - ${reason}`);
256
+ });
257
+ }
258
+
259
+ export async function createPermission(
260
+ id: string,
261
+ roleName: string,
262
+ resourceFqName: string,
263
+ c: boolean = false,
264
+ r: boolean = false,
265
+ u: boolean = false,
266
+ d: boolean = false,
267
+ env: Environment
268
+ ) {
269
+ await evalEvent(
270
+ 'CreatePermission',
271
+ {
272
+ id: id,
273
+ roleName: roleName,
274
+ resourceFqName: resourceFqName,
275
+ c: c,
276
+ r: r,
277
+ u: u,
278
+ d: d,
279
+ },
280
+ env
281
+ ).catch((reason: any) => {
282
+ logger.error(`Failed to create permission ${id} - ${reason}`);
283
+ });
284
+ }
285
+
286
+ export async function assignUserToRole(
287
+ userId: string,
288
+ roleName: string,
289
+ env: Environment
290
+ ): Promise<boolean> {
291
+ let r: boolean = true;
292
+ await evalEvent('AssignUserToRole', { userId: userId, roleName: roleName }, env).catch(
293
+ (reason: any) => {
294
+ logger.error(`Failed to assign user ${userId} to role ${roleName} - ${reason}`);
295
+ r = false;
296
+ }
297
+ );
298
+ return r;
299
+ }
300
+
301
+ export async function findUserRoles(userId: string, env: Environment): Promise<Result> {
302
+ const result: any = await evalEvent('FindUserRoles', { userId: userId }, env);
303
+ const inst: Instance | undefined = result ? (result[0] as Instance) : undefined;
304
+ if (inst) {
305
+ return inst.getRelatedInstances('UserRole');
306
+ }
307
+ return undefined;
308
+ }
309
+
310
+ type RbacPermission = {
311
+ resourceFqName: string;
312
+ c: boolean;
313
+ r: boolean;
314
+ u: boolean;
315
+ d: boolean;
316
+ };
317
+
318
+ const UserRoleCache: Map<string, string[]> = new Map();
319
+ const RolePermissionsCache: Map<string, RbacPermission[]> = new Map();
320
+
321
+ async function findRolePermissions(role: string, env: Environment): Promise<Result> {
322
+ return await evalEvent('FindRolePermissions', { role: role }, env);
323
+ }
324
+
325
+ async function updatePermissionCacheForRole(role: string, env: Environment) {
326
+ const result: any = await findRolePermissions(role, env);
327
+ if (result instanceof Array && result.length > 0) {
328
+ const roleInst: Instance = result[0] as Instance;
329
+ const permInsts: Instance[] | undefined = roleInst.getRelatedInstances('RolePermission');
330
+ if (permInsts) {
331
+ RolePermissionsCache.set(
332
+ role,
333
+ permInsts.map((inst: Instance) => {
334
+ return inst.cast<RbacPermission>();
335
+ })
336
+ );
337
+ }
338
+ }
339
+ }
340
+
341
+ export async function userHasPermissions(
342
+ userId: string,
343
+ resourceFqName: string,
344
+ perms: Set<RbacPermissionFlag>,
345
+ env: Environment
346
+ ): Promise<boolean> {
347
+ if (userId == AdminUserId) {
348
+ return true;
349
+ }
350
+ let userRoles: string[] | undefined = UserRoleCache.get(userId);
351
+ if (userRoles == undefined) {
352
+ const roles: any = await findUserRoles(userId, env);
353
+ userRoles = [];
354
+ if (roles) {
355
+ for (let i = 0; i < roles.length; ++i) {
356
+ const r: Instance = roles[i] as Instance;
357
+ const n: string = r.attributes.get('name');
358
+ userRoles.push(n);
359
+ if (!RolePermissionsCache.get(n)) {
360
+ await updatePermissionCacheForRole(n, env);
361
+ }
362
+ }
363
+ }
364
+ UserRoleCache.set(userId, userRoles);
365
+ }
366
+ const [c, r, u, d] = [
367
+ perms.has(RbacPermissionFlag.CREATE),
368
+ perms.has(RbacPermissionFlag.READ),
369
+ perms.has(RbacPermissionFlag.UPDATE),
370
+ perms.has(RbacPermissionFlag.DELETE),
371
+ ];
372
+ for (let i = 0; i < userRoles.length; ++i) {
373
+ const permInsts: RbacPermission[] | undefined = RolePermissionsCache.get(userRoles[i]);
374
+ if (permInsts) {
375
+ if (
376
+ permInsts.find((p: RbacPermission) => {
377
+ return (
378
+ p.resourceFqName == resourceFqName &&
379
+ (c ? isSqlTrue(p.c) : true) &&
380
+ (r ? isSqlTrue(p.r) : true) &&
381
+ (u ? isSqlTrue(p.u) : true) &&
382
+ (d ? isSqlTrue(p.d) : true)
383
+ );
384
+ })
385
+ )
386
+ return true;
387
+ }
388
+ }
389
+ return false;
390
+ }
391
+
392
+ const CreateOperation = new Set([RbacPermissionFlag.CREATE]);
393
+ const ReadOperation = new Set([RbacPermissionFlag.READ]);
394
+ const UpdateOperation = new Set([RbacPermissionFlag.UPDATE]);
395
+ const DeleteOperation = new Set([RbacPermissionFlag.DELETE]);
396
+
397
+ type PermCheckForUser = (
398
+ userId: string,
399
+ resourceFqName: string,
400
+ env: Environment
401
+ ) => Promise<boolean>;
402
+
403
+ function canUserPerfom(opr: Set<RbacPermissionFlag>): PermCheckForUser {
404
+ // TODO: check parent hierarchy
405
+ // TODO: cache permissions for user
406
+ async function f(userId: string, resourceFqName: string, env: Environment): Promise<boolean> {
407
+ if (userId == AdminUserId) {
408
+ return true;
409
+ }
410
+ return await userHasPermissions(userId, resourceFqName, opr, env);
411
+ }
412
+ return f;
413
+ }
414
+
415
+ export const canUserCreate = canUserPerfom(CreateOperation);
416
+ export const canUserRead = canUserPerfom(ReadOperation);
417
+ export const canUserUpdate = canUserPerfom(UpdateOperation);
418
+ export const canUserDelete = canUserPerfom(DeleteOperation);
419
+
420
+ let runtimeAuth: AgentlangAuth | undefined;
421
+
422
+ if (isNodeEnv) {
423
+ runtimeAuth = new CognitoAuth();
424
+ }
425
+
426
+ function fetchAuthImpl(): AgentlangAuth {
427
+ if (runtimeAuth) {
428
+ return runtimeAuth;
429
+ } else {
430
+ throw new Error('Auth not initialized');
431
+ }
432
+ }
433
+ export async function signUpUser(
434
+ username: string,
435
+ password: string,
436
+ userData: object,
437
+ env: Environment
438
+ ): Promise<UserInfo> {
439
+ let result: any;
440
+ await fetchAuthImpl().signUp(
441
+ username,
442
+ password,
443
+ userData ? new Map(Object.entries(userData)) : undefined,
444
+ env,
445
+ (userInfo: UserInfo) => {
446
+ result = userInfo;
447
+ }
448
+ );
449
+ return result as UserInfo;
450
+ }
451
+
452
+ export async function loginUser(
453
+ username: string,
454
+ password: string,
455
+ env: Environment
456
+ ): Promise<string> {
457
+ let result: string = '';
458
+ await fetchAuthImpl().login(username, password, env, (r: SessionInfo) => {
459
+ result = `${r.userId}/${r.sessionId}`;
460
+ });
461
+ return result;
462
+ }
463
+
464
+ export async function verifySession(token: string, env?: Environment): Promise<ActiveSessionInfo> {
465
+ if (!isAuthEnabled()) return BypassSession;
466
+ const parts = token.split('/');
467
+ const sessId = parts[1];
468
+ const needCommit = env ? false : true;
469
+ env = env ? env : new Environment();
470
+ const f = async () => {
471
+ const sess: Instance = await findSession(sessId, env);
472
+ if (sess != undefined) {
473
+ await fetchAuthImpl().verifyToken(sess.lookup('authToken'), env);
474
+ return { sessionId: sessId, userId: parts[0] };
475
+ } else {
476
+ throw new Error(`No active session for user '${parts[0]}'`);
477
+ }
478
+ };
479
+ if (needCommit) {
480
+ return await env.callInTransaction(f);
481
+ } else {
482
+ return await f();
483
+ }
484
+ }
485
+
486
+ export function requireAuth(moduleName: string, eventName: string): boolean {
487
+ const f = moduleName == CoreAuthModuleName && (eventName == 'login' || eventName == 'signup');
488
+ return !f;
489
+ }
@@ -0,0 +1,95 @@
1
+ import { default as ai } from './ai.js';
2
+ import { default as auth } from './auth.js';
3
+ import { DefaultModuleName } from '../util.js';
4
+ import { Instance, isInstanceOfType } from '../module.js';
5
+ import { Environment, parseAndEvaluateStatement } from '../interpreter.js';
6
+ import { logger } from '../logger.js';
7
+
8
+ const CoreModuleDefinition = `module ${DefaultModuleName}
9
+ entity timer {
10
+ name String @id,
11
+ duration Int,
12
+ unit @enum("millisecond", "second", "minute", "hour") @default("second"),
13
+ trigger String,
14
+ status @enum("I", "C", "R") @default("I") // Inited, Cancelled, Running
15
+ }
16
+
17
+ entity auditlog {
18
+ id UUID @id @default(uuid()),
19
+ action @enum("c", "d", "u"), // Create, Delete, Update
20
+ resource String, // __path__
21
+ timestamp DateTime @default(now()),
22
+ previous_value Any @optional,
23
+ user String,
24
+ token String @optional
25
+ }
26
+ `;
27
+ export const CoreModules: string[] = [];
28
+
29
+ export function registerCoreModules() {
30
+ CoreModules.push(CoreModuleDefinition);
31
+ [auth, ai].forEach((mdef: string) => {
32
+ CoreModules.push(mdef);
33
+ });
34
+ }
35
+
36
+ export function setTimerRunning(timerInst: Instance) {
37
+ timerInst.attributes.set('status', 'R');
38
+ }
39
+
40
+ export async function maybeCancelTimer(name: string, timer: NodeJS.Timeout, env: Environment) {
41
+ await parseAndEvaluateStatement(`{agentlang/timer {name? "${name}"}}`, undefined, env).then(
42
+ (result: any) => {
43
+ if (result == null || (result instanceof Array && result.length == 0)) {
44
+ clearInterval(timer);
45
+ }
46
+ }
47
+ );
48
+ }
49
+
50
+ async function addAudit(
51
+ env: Environment,
52
+ action: 'c' | 'd' | 'u',
53
+ resource: string,
54
+ previuos_value?: Instance
55
+ ) {
56
+ const user = env.getActiveUser();
57
+ const token = env.getActiveToken();
58
+ const newEnv = new Environment('auditlog', env).setInKernelMode(true);
59
+ const r: any = await parseAndEvaluateStatement(
60
+ `{agentlang/auditlog {
61
+ action "${action}",
62
+ resource "${resource}",
63
+ previous_value "${previuos_value ? JSON.stringify(previuos_value.asObject()) : ''}",
64
+ user "${user}",
65
+ token "${token ? token : ''}"
66
+ }}`,
67
+ undefined,
68
+ newEnv
69
+ );
70
+ if (!isInstanceOfType(r, 'agentlang/auditlog')) {
71
+ logger.warn(
72
+ `Failed to create auditlog for action ${action} and resource ${resource} for user ${user}`
73
+ );
74
+ }
75
+ }
76
+
77
+ export async function addCreateAudit(resource: string, env: Environment) {
78
+ await addAudit(env, 'c', resource);
79
+ }
80
+
81
+ export async function addDeleteAudit(
82
+ resource: string,
83
+ previous_value: Instance | undefined,
84
+ env: Environment
85
+ ) {
86
+ await addAudit(env, 'd', resource, previous_value);
87
+ }
88
+
89
+ export async function addUpdateAudit(
90
+ resource: string,
91
+ previous_value: Instance | undefined,
92
+ env: Environment
93
+ ) {
94
+ await addAudit(env, 'u', resource, previous_value);
95
+ }