1import * as cip from "@distilled.cloud/aws/cognito-identity-provider";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import { isBindingHost } from "../Lambda/Function.ts";
6import { cognitoMethods } from "./BindingHttp.ts";
7import type { UserPool } from "./UserPool.ts";
8import {
9 UserPoolAdmin,
10 type ListGroupsRequest,
11 type ListUsersRequest,
12 type UserPoolAdminClient,
13} from "./UserPoolAdmin.ts";
14
15/** The injected identifier field, in the distilled wire type. */
16type UserPoolIdField = Pick<cip.AdminGetUserRequest, "UserPoolId">;
17
18/**
19 * HTTP implementation of {@link UserPoolAdmin}: grants the admin
20 * `cognito-idp:*` actions on the bound pool's ARN and calls the Cognito
21 * HTTP API with the function's IAM credentials.
22 */
23export const UserPoolAdminHttp = Layer.effect(
24 UserPoolAdmin,
25 Effect.gen(function* () {
26 const adminCreateUser = yield* cip.adminCreateUser;
27 const adminGetUser = yield* cip.adminGetUser;
28 const adminSetUserPassword = yield* cip.adminSetUserPassword;
29 const adminUpdateUserAttributes = yield* cip.adminUpdateUserAttributes;
30 const adminDeleteUserAttributes = yield* cip.adminDeleteUserAttributes;
31 const adminDeleteUser = yield* cip.adminDeleteUser;
32 const adminConfirmSignUp = yield* cip.adminConfirmSignUp;
33 const adminDisableUser = yield* cip.adminDisableUser;
34 const adminEnableUser = yield* cip.adminEnableUser;
35 const adminResetUserPassword = yield* cip.adminResetUserPassword;
36 const adminInitiateAuth = yield* cip.adminInitiateAuth;
37 const adminRespondToAuthChallenge = yield* cip.adminRespondToAuthChallenge;
38 const adminUserGlobalSignOut = yield* cip.adminUserGlobalSignOut;
39 const adminAddUserToGroup = yield* cip.adminAddUserToGroup;
40 const adminRemoveUserFromGroup = yield* cip.adminRemoveUserFromGroup;
41 const adminListGroupsForUser = yield* cip.adminListGroupsForUser;
42 const adminSetUserMFAPreference = yield* cip.adminSetUserMFAPreference;
43 const adminLinkProviderForUser = yield* cip.adminLinkProviderForUser;
44 const adminDisableProviderForUser = yield* cip.adminDisableProviderForUser;
45 const adminGetDevice = yield* cip.adminGetDevice;
46 const adminListDevices = yield* cip.adminListDevices;
47 const adminForgetDevice = yield* cip.adminForgetDevice;
48 const adminUpdateDeviceStatus = yield* cip.adminUpdateDeviceStatus;
49 const adminListUserAuthEvents = yield* cip.adminListUserAuthEvents;
50 const adminUpdateAuthEventFeedback =
51 yield* cip.adminUpdateAuthEventFeedback;
52 const listUsers = yield* cip.listUsers;
53 const listUsersInGroup = yield* cip.listUsersInGroup;
54 const listGroups = yield* cip.listGroups;
55
56 return Effect.fn(function* <P extends UserPool>(pool: P) {
57 const UserPoolId = yield* pool.userPoolId;
58 if (!globalThis.__ALCHEMY_RUNTIME__) {
59 const host = yield* Binding.Host;
60 if (isBindingHost(host)) {
61 yield* host.bind`Allow(${host}, AWS.Cognito.UserPoolAdmin(${pool}))`({
62 policyStatements: [
63 {
64 Effect: "Allow",
65 Action: [
66 "cognito-idp:AdminAddUserToGroup",
67 "cognito-idp:AdminConfirmSignUp",
68 "cognito-idp:AdminCreateUser",
69 "cognito-idp:AdminDeleteUser",
70 "cognito-idp:AdminDeleteUserAttributes",
71 "cognito-idp:AdminDisableProviderForUser",
72 "cognito-idp:AdminDisableUser",
73 "cognito-idp:AdminEnableUser",
74 "cognito-idp:AdminForgetDevice",
75 "cognito-idp:AdminGetDevice",
76 "cognito-idp:AdminGetUser",
77 "cognito-idp:AdminInitiateAuth",
78 "cognito-idp:AdminLinkProviderForUser",
79 "cognito-idp:AdminListDevices",
80 "cognito-idp:AdminListGroupsForUser",
81 "cognito-idp:AdminListUserAuthEvents",
82 "cognito-idp:AdminRemoveUserFromGroup",
83 "cognito-idp:AdminResetUserPassword",
84 "cognito-idp:AdminRespondToAuthChallenge",
85 "cognito-idp:AdminSetUserMFAPreference",
86 "cognito-idp:AdminSetUserPassword",
87 "cognito-idp:AdminUpdateAuthEventFeedback",
88 "cognito-idp:AdminUpdateDeviceStatus",
89 "cognito-idp:AdminUpdateUserAttributes",
90 "cognito-idp:AdminUserGlobalSignOut",
91 "cognito-idp:ListGroups",
92 "cognito-idp:ListUsers",
93 "cognito-idp:ListUsersInGroup",
94 ],
95 Resource: [pool.userPoolArn],
96 },
97 ],
98 });
99 }
100 }
101 const methods = cognitoMethods(
102 "AWS.Cognito.UserPoolAdmin",
103 pool.LogicalId,
104 );
105 const withPool = methods.injecting(
106 Effect.map(UserPoolId, (id): UserPoolIdField => ({ UserPoolId: id })),
107 );
108 const adminClient: UserPoolAdminClient = {
109 adminCreateUser: withPool("adminCreateUser", adminCreateUser),
110 adminGetUser: withPool("adminGetUser", adminGetUser),
111 adminSetUserPassword: withPool(
112 "adminSetUserPassword",
113 adminSetUserPassword,
114 ),
115 adminUpdateUserAttributes: withPool(
116 "adminUpdateUserAttributes",
117 adminUpdateUserAttributes,
118 ),
119 adminDeleteUserAttributes: withPool(
120 "adminDeleteUserAttributes",
121 adminDeleteUserAttributes,
122 ),
123 adminDeleteUser: withPool("adminDeleteUser", adminDeleteUser),
124 adminConfirmSignUp: withPool("adminConfirmSignUp", adminConfirmSignUp),
125 adminDisableUser: withPool("adminDisableUser", adminDisableUser),
126 adminEnableUser: withPool("adminEnableUser", adminEnableUser),
127 adminResetUserPassword: withPool(
128 "adminResetUserPassword",
129 adminResetUserPassword,
130 ),
131 adminInitiateAuth: withPool("adminInitiateAuth", adminInitiateAuth),
132 adminRespondToAuthChallenge: withPool(
133 "adminRespondToAuthChallenge",
134 adminRespondToAuthChallenge,
135 ),
136 adminUserGlobalSignOut: withPool(
137 "adminUserGlobalSignOut",
138 adminUserGlobalSignOut,
139 ),
140 adminAddUserToGroup: withPool(
141 "adminAddUserToGroup",
142 adminAddUserToGroup,
143 ),
144 adminRemoveUserFromGroup: withPool(
145 "adminRemoveUserFromGroup",
146 adminRemoveUserFromGroup,
147 ),
148 adminListGroupsForUser: withPool(
149 "adminListGroupsForUser",
150 adminListGroupsForUser,
151 ),
152 adminSetUserMFAPreference: withPool(
153 "adminSetUserMFAPreference",
154 adminSetUserMFAPreference,
155 ),
156 adminLinkProviderForUser: withPool(
157 "adminLinkProviderForUser",
158 adminLinkProviderForUser,
159 ),
160 adminDisableProviderForUser: withPool(
161 "adminDisableProviderForUser",
162 adminDisableProviderForUser,
163 ),
164 adminGetDevice: withPool("adminGetDevice", adminGetDevice),
165 adminListDevices: withPool("adminListDevices", adminListDevices),
166 adminForgetDevice: withPool("adminForgetDevice", adminForgetDevice),
167 adminUpdateDeviceStatus: withPool(
168 "adminUpdateDeviceStatus",
169 adminUpdateDeviceStatus,
170 ),
171 adminListUserAuthEvents: withPool(
172 "adminListUserAuthEvents",
173 adminListUserAuthEvents,
174 ),
175 adminUpdateAuthEventFeedback: withPool(
176 "adminUpdateAuthEventFeedback",
177 adminUpdateAuthEventFeedback,
178 ),
179 listUsersInGroup: withPool("listUsersInGroup", listUsersInGroup),
180 // optional-request list operations stay bespoke (the helper's
181 // wrapped methods take a required request object)
182 listUsers: Effect.fn(
183 `AWS.Cognito.UserPoolAdmin.listUsers(${pool.LogicalId})`,
184 )(function* (request: ListUsersRequest = {}) {
185 return yield* listUsers({
186 ...request,
187 UserPoolId: yield* UserPoolId,
188 });
189 }),
190 listGroups: Effect.fn(
191 `AWS.Cognito.UserPoolAdmin.listGroups(${pool.LogicalId})`,
192 )(function* (request: ListGroupsRequest = {}) {
193 return yield* listGroups({
194 ...request,
195 UserPoolId: yield* UserPoolId,
196 });
197 }),
198 };
199 return adminClient;
200 });
201 }),
202);