@awsless/cli 0.0.46-local.45 → 0.0.46-local.47
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/dist/bin.js +457 -34
- package/dist/handlers/bundle.js +3 -1
- package/package.json +15 -15
package/dist/bin.js
CHANGED
|
@@ -152672,9 +152672,18 @@ class TypeObject {
|
|
|
152672
152672
|
|
|
152673
152673
|
// src/feature/auth/dev.ts
|
|
152674
152674
|
import {
|
|
152675
|
+
AdminAddUserToGroupCommand,
|
|
152676
|
+
AdminCreateUserCommand,
|
|
152677
|
+
AdminGetUserCommand,
|
|
152678
|
+
AdminListGroupsForUserCommand,
|
|
152679
|
+
AdminRemoveUserFromGroupCommand,
|
|
152680
|
+
AdminSetUserPasswordCommand,
|
|
152675
152681
|
CognitoIdentityProviderClient,
|
|
152676
152682
|
ListUserPoolClientsCommand,
|
|
152677
|
-
ListUserPoolsCommand
|
|
152683
|
+
ListUserPoolsCommand,
|
|
152684
|
+
ListUsersCommand,
|
|
152685
|
+
UserNotFoundException,
|
|
152686
|
+
UsernameExistsException
|
|
152678
152687
|
} from "@aws-sdk/client-cognito-identity-provider";
|
|
152679
152688
|
var authOnDev = async (ctx) => {
|
|
152680
152689
|
const ids = Object.keys(ctx.appConfig.auth ?? {});
|
|
@@ -152745,13 +152754,199 @@ var authOnDev = async (ctx) => {
|
|
|
152745
152754
|
for (const [id, pool] of Object.entries(pools)) {
|
|
152746
152755
|
ctx.addEnv(`AUTH_${constantCase(id)}_USER_POOL_ID`, pool.userPoolId);
|
|
152747
152756
|
ctx.addEnv(`AUTH_${constantCase(id)}_CLIENT_ID`, pool.clientId);
|
|
152757
|
+
}
|
|
152758
|
+
for (const id of ids) {
|
|
152748
152759
|
ctx.registerResource({
|
|
152749
152760
|
kind: "auth",
|
|
152750
152761
|
id,
|
|
152751
|
-
detail:
|
|
152762
|
+
detail: pools[id]?.userPoolId ?? "not deployed"
|
|
152752
152763
|
});
|
|
152753
152764
|
}
|
|
152754
152765
|
};
|
|
152766
|
+
var createAuthAdmin = (props) => {
|
|
152767
|
+
let client;
|
|
152768
|
+
const getClient = async () => {
|
|
152769
|
+
client ??= new CognitoIdentityProviderClient({
|
|
152770
|
+
region: props.appConfig.region,
|
|
152771
|
+
credentials: await getCredentials(props.appConfig.profile)
|
|
152772
|
+
});
|
|
152773
|
+
return client;
|
|
152774
|
+
};
|
|
152775
|
+
const getPool = (id) => {
|
|
152776
|
+
const authProps = props.appConfig.auth?.[id];
|
|
152777
|
+
const resolved = props.resolvedPools()?.[id];
|
|
152778
|
+
if (!authProps) {
|
|
152779
|
+
throw new Error(`The auth userpool "${id}" doesn't exist.`);
|
|
152780
|
+
}
|
|
152781
|
+
if (!resolved) {
|
|
152782
|
+
throw new Error(`The auth userpool "${id}" isn't deployed yet.`);
|
|
152783
|
+
}
|
|
152784
|
+
return { ...authProps, userPoolId: resolved.userPoolId };
|
|
152785
|
+
};
|
|
152786
|
+
const validatePassword = (pool, value) => {
|
|
152787
|
+
if (!value) {
|
|
152788
|
+
return "A password is required";
|
|
152789
|
+
}
|
|
152790
|
+
if (value.length < pool.password.minLength) {
|
|
152791
|
+
return `The password min length is ${pool.password.minLength}`;
|
|
152792
|
+
}
|
|
152793
|
+
if (pool.password.lowercase && value.toUpperCase() === value) {
|
|
152794
|
+
return `The password should include lowercase characters`;
|
|
152795
|
+
}
|
|
152796
|
+
if (pool.password.uppercase && value.toLowerCase() === value) {
|
|
152797
|
+
return `The password should include uppercase characters`;
|
|
152798
|
+
}
|
|
152799
|
+
if (pool.password.numbers && !/\d/.test(value)) {
|
|
152800
|
+
return `The password should include numbers`;
|
|
152801
|
+
}
|
|
152802
|
+
if (pool.password.symbols && !/[ `!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/.test(value)) {
|
|
152803
|
+
return `The password should include symbols`;
|
|
152804
|
+
}
|
|
152805
|
+
return;
|
|
152806
|
+
};
|
|
152807
|
+
const validateGroups = (pool, groups) => {
|
|
152808
|
+
for (const group4 of groups) {
|
|
152809
|
+
if (!pool.groups.includes(group4)) {
|
|
152810
|
+
throw new Error(`The group "${group4}" doesn't exist.`);
|
|
152811
|
+
}
|
|
152812
|
+
}
|
|
152813
|
+
};
|
|
152814
|
+
const listUserGroups = async (userPoolId, username) => {
|
|
152815
|
+
const client2 = await getClient();
|
|
152816
|
+
const groups = [];
|
|
152817
|
+
let token;
|
|
152818
|
+
do {
|
|
152819
|
+
const result = await client2.send(new AdminListGroupsForUserCommand({
|
|
152820
|
+
UserPoolId: userPoolId,
|
|
152821
|
+
Username: username,
|
|
152822
|
+
NextToken: token
|
|
152823
|
+
}));
|
|
152824
|
+
groups.push(...result.Groups?.map((group4) => group4.GroupName) ?? []);
|
|
152825
|
+
token = result.NextToken;
|
|
152826
|
+
} while (token);
|
|
152827
|
+
return groups;
|
|
152828
|
+
};
|
|
152829
|
+
return {
|
|
152830
|
+
describePool(id) {
|
|
152831
|
+
const pool = getPool(id);
|
|
152832
|
+
return {
|
|
152833
|
+
groups: pool.groups
|
|
152834
|
+
};
|
|
152835
|
+
},
|
|
152836
|
+
async listUsers(id) {
|
|
152837
|
+
const pool = getPool(id);
|
|
152838
|
+
const client2 = await getClient();
|
|
152839
|
+
const users = [];
|
|
152840
|
+
let token;
|
|
152841
|
+
do {
|
|
152842
|
+
const result = await client2.send(new ListUsersCommand({
|
|
152843
|
+
UserPoolId: pool.userPoolId,
|
|
152844
|
+
PaginationToken: token
|
|
152845
|
+
}));
|
|
152846
|
+
for (const user of result.Users ?? []) {
|
|
152847
|
+
users.push({
|
|
152848
|
+
username: user.Username,
|
|
152849
|
+
email: user.Attributes?.find((a3) => a3.Name === "email")?.Value,
|
|
152850
|
+
status: user.UserStatus,
|
|
152851
|
+
enabled: user.Enabled ?? true,
|
|
152852
|
+
createdAt: user.UserCreateDate?.toISOString(),
|
|
152853
|
+
groups: []
|
|
152854
|
+
});
|
|
152855
|
+
}
|
|
152856
|
+
token = result.PaginationToken;
|
|
152857
|
+
} while (token && users.length < 500);
|
|
152858
|
+
await Promise.all(users.map(async (user) => {
|
|
152859
|
+
user.groups = await listUserGroups(pool.userPoolId, user.username);
|
|
152860
|
+
}));
|
|
152861
|
+
return users.sort((a3, b5) => a3.username.localeCompare(b5.username));
|
|
152862
|
+
},
|
|
152863
|
+
async createUser(id, input) {
|
|
152864
|
+
const pool = getPool(id);
|
|
152865
|
+
if (!input.username) {
|
|
152866
|
+
throw new Error("A username is required");
|
|
152867
|
+
}
|
|
152868
|
+
const issue = validatePassword(pool, input.password);
|
|
152869
|
+
if (issue) {
|
|
152870
|
+
throw new Error(issue);
|
|
152871
|
+
}
|
|
152872
|
+
validateGroups(pool, input.groups);
|
|
152873
|
+
const client2 = await getClient();
|
|
152874
|
+
try {
|
|
152875
|
+
await client2.send(new AdminCreateUserCommand({
|
|
152876
|
+
UserPoolId: pool.userPoolId,
|
|
152877
|
+
Username: input.username,
|
|
152878
|
+
TemporaryPassword: input.password
|
|
152879
|
+
}));
|
|
152880
|
+
} catch (error3) {
|
|
152881
|
+
if (error3 instanceof UsernameExistsException) {
|
|
152882
|
+
throw new Error("The user already exists");
|
|
152883
|
+
}
|
|
152884
|
+
throw error3;
|
|
152885
|
+
}
|
|
152886
|
+
await client2.send(new AdminSetUserPasswordCommand({
|
|
152887
|
+
UserPoolId: pool.userPoolId,
|
|
152888
|
+
Username: input.username,
|
|
152889
|
+
Password: input.password,
|
|
152890
|
+
Permanent: true
|
|
152891
|
+
}));
|
|
152892
|
+
for (const group4 of input.groups) {
|
|
152893
|
+
await client2.send(new AdminAddUserToGroupCommand({
|
|
152894
|
+
UserPoolId: pool.userPoolId,
|
|
152895
|
+
Username: input.username,
|
|
152896
|
+
GroupName: group4
|
|
152897
|
+
}));
|
|
152898
|
+
}
|
|
152899
|
+
},
|
|
152900
|
+
async updateUser(id, input) {
|
|
152901
|
+
const pool = getPool(id);
|
|
152902
|
+
validateGroups(pool, input.groups);
|
|
152903
|
+
if (input.password) {
|
|
152904
|
+
const issue = validatePassword(pool, input.password);
|
|
152905
|
+
if (issue) {
|
|
152906
|
+
throw new Error(issue);
|
|
152907
|
+
}
|
|
152908
|
+
}
|
|
152909
|
+
const client2 = await getClient();
|
|
152910
|
+
let oldGroups;
|
|
152911
|
+
try {
|
|
152912
|
+
await client2.send(new AdminGetUserCommand({
|
|
152913
|
+
UserPoolId: pool.userPoolId,
|
|
152914
|
+
Username: input.username
|
|
152915
|
+
}));
|
|
152916
|
+
oldGroups = await listUserGroups(pool.userPoolId, input.username);
|
|
152917
|
+
} catch (error3) {
|
|
152918
|
+
if (error3 instanceof UserNotFoundException) {
|
|
152919
|
+
throw new Error("The user does not exist");
|
|
152920
|
+
}
|
|
152921
|
+
throw error3;
|
|
152922
|
+
}
|
|
152923
|
+
if (input.password) {
|
|
152924
|
+
await client2.send(new AdminSetUserPasswordCommand({
|
|
152925
|
+
UserPoolId: pool.userPoolId,
|
|
152926
|
+
Username: input.username,
|
|
152927
|
+
Password: input.password,
|
|
152928
|
+
Permanent: true
|
|
152929
|
+
}));
|
|
152930
|
+
}
|
|
152931
|
+
const removed = oldGroups.filter((group4) => !input.groups.includes(group4));
|
|
152932
|
+
const added = input.groups.filter((group4) => !oldGroups.includes(group4));
|
|
152933
|
+
for (const group4 of removed) {
|
|
152934
|
+
await client2.send(new AdminRemoveUserFromGroupCommand({
|
|
152935
|
+
UserPoolId: pool.userPoolId,
|
|
152936
|
+
Username: input.username,
|
|
152937
|
+
GroupName: group4
|
|
152938
|
+
}));
|
|
152939
|
+
}
|
|
152940
|
+
for (const group4 of added) {
|
|
152941
|
+
await client2.send(new AdminAddUserToGroupCommand({
|
|
152942
|
+
UserPoolId: pool.userPoolId,
|
|
152943
|
+
Username: input.username,
|
|
152944
|
+
GroupName: group4
|
|
152945
|
+
}));
|
|
152946
|
+
}
|
|
152947
|
+
}
|
|
152948
|
+
};
|
|
152949
|
+
};
|
|
152755
152950
|
|
|
152756
152951
|
// src/feature/auth/index.ts
|
|
152757
152952
|
import { toDays as toDays4, toHours } from "@awsless/duration";
|
|
@@ -154827,6 +155022,9 @@ var decodeAwsChunked = (body) => {
|
|
|
154827
155022
|
}
|
|
154828
155023
|
return Buffer.concat(chunks);
|
|
154829
155024
|
};
|
|
155025
|
+
var stripAnsi2 = (line) => {
|
|
155026
|
+
return line.replaceAll(/\x1b\[[0-9;?]*[a-zA-Z]/g, "");
|
|
155027
|
+
};
|
|
154830
155028
|
|
|
154831
155029
|
// src/dev/servers/ssm.ts
|
|
154832
155030
|
var createSsmServer = (props) => {
|
|
@@ -158065,7 +158263,20 @@ var startDevRouter = async (props) => {
|
|
|
158065
158263
|
}
|
|
158066
158264
|
const body = Buffer.from(await request.arrayBuffer());
|
|
158067
158265
|
const sourceIp = server2.requestIP(request)?.address ?? "127.0.0.1";
|
|
158068
|
-
|
|
158266
|
+
let result;
|
|
158267
|
+
try {
|
|
158268
|
+
result = await props.dispatch(formatWebEvent(request, route, body, url, sourceIp));
|
|
158269
|
+
} catch (error3) {
|
|
158270
|
+
props.onError?.(error3, route.routeKey);
|
|
158271
|
+
const detail = error3 instanceof Error ? error3.stack ?? error3.message : String(error3);
|
|
158272
|
+
return new Response(`500: Internal Error
|
|
158273
|
+
|
|
158274
|
+
${route.routeKey}
|
|
158275
|
+
${detail}`, {
|
|
158276
|
+
status: 500,
|
|
158277
|
+
headers: { "content-type": "text/plain" }
|
|
158278
|
+
});
|
|
158279
|
+
}
|
|
158069
158280
|
return toResponse(result);
|
|
158070
158281
|
},
|
|
158071
158282
|
websocket: {
|
|
@@ -158850,7 +159061,7 @@ var planStaticRoutes = (files, sitePath) => {
|
|
|
158850
159061
|
};
|
|
158851
159062
|
|
|
158852
159063
|
// src/feature/site/dev.ts
|
|
158853
|
-
var
|
|
159064
|
+
var stripAnsi3 = (line) => {
|
|
158854
159065
|
return line.replaceAll(/\x1b\[[0-9;?]*[a-zA-Z]/g, "");
|
|
158855
159066
|
};
|
|
158856
159067
|
var binPath = (from) => {
|
|
@@ -158903,7 +159114,7 @@ var siteOnDev = async (ctx) => {
|
|
|
158903
159114
|
const capture = (chunk3) => {
|
|
158904
159115
|
for (const raw of chunk3.toString().split(`
|
|
158905
159116
|
`)) {
|
|
158906
|
-
const line =
|
|
159117
|
+
const line = stripAnsi3(raw);
|
|
158907
159118
|
if (line.trim() === "") {
|
|
158908
159119
|
continue;
|
|
158909
159120
|
}
|
|
@@ -162707,7 +162918,7 @@ var routerFeature = defineFeature({
|
|
|
162707
162918
|
for (const [id, patterns] of Object.entries(stackConfig.routes ?? {})) {
|
|
162708
162919
|
for (const pattern of Object.keys(patterns)) {
|
|
162709
162920
|
const slug = kebabCase(pattern).slice(0, 20);
|
|
162710
|
-
const routeKey = formatRouteKey(stackConfig.name, "route", `${slug || "root"}-${shortId(
|
|
162921
|
+
const routeKey = formatRouteKey(stackConfig.name, "route", `${slug || "root"}-${shortId(pattern)}`);
|
|
162711
162922
|
ctx.addRoute({
|
|
162712
162923
|
routerId: id,
|
|
162713
162924
|
pattern,
|
|
@@ -164666,11 +164877,11 @@ var deploy = (program3) => {
|
|
|
164666
164877
|
|
|
164667
164878
|
// src/cli/command/auth/user/create.ts
|
|
164668
164879
|
import {
|
|
164669
|
-
AdminAddUserToGroupCommand,
|
|
164670
|
-
AdminCreateUserCommand,
|
|
164671
|
-
AdminSetUserPasswordCommand,
|
|
164880
|
+
AdminAddUserToGroupCommand as AdminAddUserToGroupCommand2,
|
|
164881
|
+
AdminCreateUserCommand as AdminCreateUserCommand2,
|
|
164882
|
+
AdminSetUserPasswordCommand as AdminSetUserPasswordCommand2,
|
|
164672
164883
|
CognitoIdentityProviderClient as CognitoIdentityProviderClient2,
|
|
164673
|
-
UsernameExistsException
|
|
164884
|
+
UsernameExistsException as UsernameExistsException2
|
|
164674
164885
|
} from "@aws-sdk/client-cognito-identity-provider";
|
|
164675
164886
|
var create = (program3) => {
|
|
164676
164887
|
program3.command("create").description("Create an user in your userpool").option("--pool <name>", "The auth userpool name").option("--username <username>", "The username for the new user").option("--password <password>", "The password for the new user").option("--groups <groups...>", "The groups to add the new user to").action(async (options) => {
|
|
@@ -164818,18 +165029,18 @@ var create = (program3) => {
|
|
|
164818
165029
|
errorMessage: "Failed creating user.",
|
|
164819
165030
|
async task() {
|
|
164820
165031
|
try {
|
|
164821
|
-
await client.send(new
|
|
165032
|
+
await client.send(new AdminCreateUserCommand2({
|
|
164822
165033
|
UserPoolId: userPoolId,
|
|
164823
165034
|
Username: username,
|
|
164824
165035
|
TemporaryPassword: password2
|
|
164825
165036
|
}));
|
|
164826
165037
|
} catch (error3) {
|
|
164827
|
-
if (error3 instanceof
|
|
165038
|
+
if (error3 instanceof UsernameExistsException2) {
|
|
164828
165039
|
throw new ExpectedError("User already exists");
|
|
164829
165040
|
}
|
|
164830
165041
|
throw error3;
|
|
164831
165042
|
}
|
|
164832
|
-
await client.send(new
|
|
165043
|
+
await client.send(new AdminSetUserPasswordCommand2({
|
|
164833
165044
|
UserPoolId: userPoolId,
|
|
164834
165045
|
Username: username,
|
|
164835
165046
|
Password: password2,
|
|
@@ -164837,7 +165048,7 @@ var create = (program3) => {
|
|
|
164837
165048
|
}));
|
|
164838
165049
|
if (groups.length > 0) {
|
|
164839
165050
|
for (const group4 of groups) {
|
|
164840
|
-
await client.send(new
|
|
165051
|
+
await client.send(new AdminAddUserToGroupCommand2({
|
|
164841
165052
|
UserPoolId: userPoolId,
|
|
164842
165053
|
Username: username,
|
|
164843
165054
|
GroupName: group4
|
|
@@ -164852,13 +165063,13 @@ var create = (program3) => {
|
|
|
164852
165063
|
|
|
164853
165064
|
// src/cli/command/auth/user/update.ts
|
|
164854
165065
|
import {
|
|
164855
|
-
AdminAddUserToGroupCommand as
|
|
164856
|
-
AdminGetUserCommand,
|
|
164857
|
-
AdminListGroupsForUserCommand,
|
|
164858
|
-
AdminRemoveUserFromGroupCommand,
|
|
164859
|
-
AdminSetUserPasswordCommand as
|
|
165066
|
+
AdminAddUserToGroupCommand as AdminAddUserToGroupCommand3,
|
|
165067
|
+
AdminGetUserCommand as AdminGetUserCommand2,
|
|
165068
|
+
AdminListGroupsForUserCommand as AdminListGroupsForUserCommand2,
|
|
165069
|
+
AdminRemoveUserFromGroupCommand as AdminRemoveUserFromGroupCommand2,
|
|
165070
|
+
AdminSetUserPasswordCommand as AdminSetUserPasswordCommand3,
|
|
164860
165071
|
CognitoIdentityProviderClient as CognitoIdentityProviderClient3,
|
|
164861
|
-
UserNotFoundException
|
|
165072
|
+
UserNotFoundException as UserNotFoundException2
|
|
164862
165073
|
} from "@aws-sdk/client-cognito-identity-provider";
|
|
164863
165074
|
var update = (program3) => {
|
|
164864
165075
|
program3.command("update").description("Update an user in your userpool").option("--pool <name>", "The auth userpool name").option("--username <username>", "The username of the user").option("--password <password>", "The new password for the user").option("--groups <groups...>", "The groups the user should be in, replacing the current groups").action(async (options) => {
|
|
@@ -164955,12 +165166,12 @@ var update = (program3) => {
|
|
|
164955
165166
|
errorMessage: `Failed fetching user info.`,
|
|
164956
165167
|
async task() {
|
|
164957
165168
|
try {
|
|
164958
|
-
await client.send(new
|
|
165169
|
+
await client.send(new AdminGetUserCommand2({
|
|
164959
165170
|
UserPoolId: userPoolId,
|
|
164960
165171
|
Username: username
|
|
164961
165172
|
}));
|
|
164962
165173
|
} catch (error3) {
|
|
164963
|
-
if (error3 instanceof
|
|
165174
|
+
if (error3 instanceof UserNotFoundException2) {
|
|
164964
165175
|
throw new ExpectedError("User does not exist");
|
|
164965
165176
|
}
|
|
164966
165177
|
throw error3;
|
|
@@ -164968,7 +165179,7 @@ var update = (program3) => {
|
|
|
164968
165179
|
const groups = [];
|
|
164969
165180
|
let token;
|
|
164970
165181
|
do {
|
|
164971
|
-
const result = await client.send(new
|
|
165182
|
+
const result = await client.send(new AdminListGroupsForUserCommand2({
|
|
164972
165183
|
UserPoolId: userPoolId,
|
|
164973
165184
|
Username: username,
|
|
164974
165185
|
NextToken: token
|
|
@@ -165042,7 +165253,7 @@ var update = (program3) => {
|
|
|
165042
165253
|
errorMessage: "Failed updating user.",
|
|
165043
165254
|
async task() {
|
|
165044
165255
|
if (password2) {
|
|
165045
|
-
await client.send(new
|
|
165256
|
+
await client.send(new AdminSetUserPasswordCommand3({
|
|
165046
165257
|
UserPoolId: userPoolId,
|
|
165047
165258
|
Username: username,
|
|
165048
165259
|
Password: password2,
|
|
@@ -165054,14 +165265,14 @@ var update = (program3) => {
|
|
|
165054
165265
|
const removedGroups = oldGroupSet.difference(newGroupSet);
|
|
165055
165266
|
const addedGroups = newGroupSet.difference(oldGroupSet);
|
|
165056
165267
|
for (const group4 of removedGroups) {
|
|
165057
|
-
await client.send(new
|
|
165268
|
+
await client.send(new AdminRemoveUserFromGroupCommand2({
|
|
165058
165269
|
UserPoolId: userPoolId,
|
|
165059
165270
|
Username: username,
|
|
165060
165271
|
GroupName: group4
|
|
165061
165272
|
}));
|
|
165062
165273
|
}
|
|
165063
165274
|
for (const group4 of addedGroups) {
|
|
165064
|
-
await client.send(new
|
|
165275
|
+
await client.send(new AdminAddUserToGroupCommand3({
|
|
165065
165276
|
UserPoolId: userPoolId,
|
|
165066
165277
|
Username: username,
|
|
165067
165278
|
GroupName: group4
|
|
@@ -165077,7 +165288,7 @@ var update = (program3) => {
|
|
|
165077
165288
|
import {
|
|
165078
165289
|
AdminDeleteUserCommand,
|
|
165079
165290
|
CognitoIdentityProviderClient as CognitoIdentityProviderClient4,
|
|
165080
|
-
UserNotFoundException as
|
|
165291
|
+
UserNotFoundException as UserNotFoundException3
|
|
165081
165292
|
} from "@aws-sdk/client-cognito-identity-provider";
|
|
165082
165293
|
var del10 = (program3) => {
|
|
165083
165294
|
program3.command("delete").description("Delete an user from your userpool").option("--pool <name>", "The auth userpool name").option("--username <username>", "The username of the user to delete").action(async (options) => {
|
|
@@ -165168,7 +165379,7 @@ var del10 = (program3) => {
|
|
|
165168
165379
|
Username: username
|
|
165169
165380
|
}));
|
|
165170
165381
|
} catch (error3) {
|
|
165171
|
-
if (error3 instanceof
|
|
165382
|
+
if (error3 instanceof UserNotFoundException3) {
|
|
165172
165383
|
throw new ExpectedError(`User doesn't exist`);
|
|
165173
165384
|
}
|
|
165174
165385
|
throw error3;
|
|
@@ -166503,8 +166714,18 @@ var createBundleWorker = (props) => {
|
|
|
166503
166714
|
AWSLESS_DEV_WORKER_PORT: String(port)
|
|
166504
166715
|
}
|
|
166505
166716
|
});
|
|
166506
|
-
|
|
166507
|
-
|
|
166717
|
+
const capture = (stream2) => (chunk3) => {
|
|
166718
|
+
process[stream2].write(chunk3);
|
|
166719
|
+
for (const raw of chunk3.toString().split(`
|
|
166720
|
+
`)) {
|
|
166721
|
+
const line = stripAnsi2(raw);
|
|
166722
|
+
if (line.trim() !== "") {
|
|
166723
|
+
props.onOutput?.(line, stream2);
|
|
166724
|
+
}
|
|
166725
|
+
}
|
|
166726
|
+
};
|
|
166727
|
+
child.stdout?.on("data", capture("stdout"));
|
|
166728
|
+
child.stderr?.on("data", capture("stderr"));
|
|
166508
166729
|
child.on("exit", (code) => {
|
|
166509
166730
|
if (code !== null && code !== 0) {
|
|
166510
166731
|
debug(`Bundle worker exited with code ${code}`);
|
|
@@ -166611,6 +166832,7 @@ var dashboardHtml = `<!doctype html>
|
|
|
166611
166832
|
.logs .line { display: flex; gap: 8px; padding: 1px 0; }
|
|
166612
166833
|
.logs .time { color: var(--muted); flex-shrink: 0; }
|
|
166613
166834
|
.logs .text { white-space: pre-wrap; word-break: break-word; }
|
|
166835
|
+
.logs .line.error .text { color: var(--bad); }
|
|
166614
166836
|
.config-form { display: flex; flex-direction: column; gap: 8px; max-width: 520px; }
|
|
166615
166837
|
.config-form .field { display: grid; grid-template-columns: 180px 1fr; gap: 12px; align-items: center; }
|
|
166616
166838
|
.config-form .name { color: var(--muted); overflow-wrap: anywhere; }
|
|
@@ -166623,6 +166845,8 @@ var dashboardHtml = `<!doctype html>
|
|
|
166623
166845
|
font: inherit;
|
|
166624
166846
|
}
|
|
166625
166847
|
.config-form input::placeholder { color: var(--muted); }
|
|
166848
|
+
.groups { display: flex; flex-wrap: wrap; gap: 4px 16px; }
|
|
166849
|
+
.groups .group { display: flex; align-items: center; gap: 4px; cursor: pointer; }
|
|
166626
166850
|
nav {
|
|
166627
166851
|
border-right: 1px solid var(--border);
|
|
166628
166852
|
overflow-y: auto;
|
|
@@ -166842,6 +167066,7 @@ const GROUPS = [
|
|
|
166842
167066
|
['config', 'Config'],
|
|
166843
167067
|
['auth', 'Auth'],
|
|
166844
167068
|
['email', 'Emails'],
|
|
167069
|
+
['worker', 'Worker'],
|
|
166845
167070
|
['route', 'Routes'],
|
|
166846
167071
|
]
|
|
166847
167072
|
|
|
@@ -167127,7 +167352,7 @@ const attachLogFeed = (main, channel) => {
|
|
|
167127
167352
|
const data = JSON.parse(message.data)
|
|
167128
167353
|
|
|
167129
167354
|
feed.querySelector('.empty')?.remove()
|
|
167130
|
-
feed.append($('div', { className: 'line' }, [
|
|
167355
|
+
feed.append($('div', { className: 'line' + (data.error ? ' error' : '') }, [
|
|
167131
167356
|
$('span', { className: 'time' }, new Date(data.date).toLocaleTimeString()),
|
|
167132
167357
|
$('span', { className: 'text' }, data.line),
|
|
167133
167358
|
]))
|
|
@@ -167457,6 +167682,138 @@ const configPanel = async (main) => {
|
|
|
167457
167682
|
main.append(form, $('div', { className: 'actions' }, [save, status]))
|
|
167458
167683
|
}
|
|
167459
167684
|
|
|
167685
|
+
// The users of a real deployed auth pool, with the same create &
|
|
167686
|
+
// group-update operations as the auth user cli commands.
|
|
167687
|
+
const authPanel = async (main, r) => {
|
|
167688
|
+
const holder = $('div', {}, $('p', { className: 'empty' }, 'Loading users...'))
|
|
167689
|
+
main.append(holder)
|
|
167690
|
+
|
|
167691
|
+
const groupBoxes = (groups, selected) => {
|
|
167692
|
+
const boxes = new Map()
|
|
167693
|
+
const row = $('div', { className: 'groups' })
|
|
167694
|
+
|
|
167695
|
+
for (const group of groups) {
|
|
167696
|
+
const box = $('input', { type: 'checkbox', checked: selected.includes(group) })
|
|
167697
|
+
boxes.set(group, box)
|
|
167698
|
+
row.append($('label', { className: 'group' }, [box, ' ' + group]))
|
|
167699
|
+
}
|
|
167700
|
+
|
|
167701
|
+
return { row, selected: () => [...boxes].filter(([, box]) => box.checked).map(([group]) => group) }
|
|
167702
|
+
}
|
|
167703
|
+
|
|
167704
|
+
try {
|
|
167705
|
+
const data = await api('/api/auth?pool=' + encodeURIComponent(r.id))
|
|
167706
|
+
holder.innerHTML = ''
|
|
167707
|
+
|
|
167708
|
+
// --------------------------------------------------------------
|
|
167709
|
+
// The user list, each row expanding into its group/password form.
|
|
167710
|
+
|
|
167711
|
+
if (data.users.length === 0) {
|
|
167712
|
+
holder.append($('p', { className: 'empty' }, 'The pool has no users.'))
|
|
167713
|
+
} else {
|
|
167714
|
+
const editRow = $('tr', { style: 'display: none' })
|
|
167715
|
+
const table = $('table', {}, [
|
|
167716
|
+
$('tr', {}, ['username', 'email', 'status', 'groups', 'created'].map(c => $('th', {}, c))),
|
|
167717
|
+
])
|
|
167718
|
+
|
|
167719
|
+
for (const user of data.users) {
|
|
167720
|
+
const row = $('tr', {}, [
|
|
167721
|
+
$('td', {}, user.username),
|
|
167722
|
+
$('td', {}, user.email ?? ''),
|
|
167723
|
+
$('td', {}, user.enabled ? (user.status ?? '') : 'DISABLED'),
|
|
167724
|
+
$('td', {}, user.groups.join(', ')),
|
|
167725
|
+
$('td', {}, user.createdAt ? new Date(user.createdAt).toLocaleString() : ''),
|
|
167726
|
+
])
|
|
167727
|
+
|
|
167728
|
+
row.style.cursor = 'pointer'
|
|
167729
|
+
row.onclick = () => {
|
|
167730
|
+
const groups = groupBoxes(data.groups, user.groups)
|
|
167731
|
+
const password = $('input', { type: 'password', placeholder: 'unchanged', spellcheck: false })
|
|
167732
|
+
const status = $('span', { className: 'status' })
|
|
167733
|
+
const save = $('button', { className: 'primary', textContent: 'Save' })
|
|
167734
|
+
|
|
167735
|
+
save.onclick = async () => {
|
|
167736
|
+
save.disabled = true
|
|
167737
|
+
try {
|
|
167738
|
+
await api('/api/auth/update', {
|
|
167739
|
+
method: 'POST',
|
|
167740
|
+
body: JSON.stringify({
|
|
167741
|
+
pool: r.id,
|
|
167742
|
+
username: user.username,
|
|
167743
|
+
password: password.value,
|
|
167744
|
+
groups: groups.selected(),
|
|
167745
|
+
}),
|
|
167746
|
+
})
|
|
167747
|
+
main.innerHTML = ''
|
|
167748
|
+
renderResource(main)
|
|
167749
|
+
return
|
|
167750
|
+
} catch (error) {
|
|
167751
|
+
status.textContent = String(error.message ?? error)
|
|
167752
|
+
}
|
|
167753
|
+
save.disabled = false
|
|
167754
|
+
}
|
|
167755
|
+
|
|
167756
|
+
editRow.innerHTML = ''
|
|
167757
|
+
editRow.style.display = ''
|
|
167758
|
+
editRow.append($('td', { colSpan: 5 }, $('div', { className: 'config-form' }, [
|
|
167759
|
+
$('label', { className: 'field' }, [$('span', { className: 'name' }, 'groups'), groups.row]),
|
|
167760
|
+
$('label', { className: 'field' }, [$('span', { className: 'name' }, 'new password'), password]),
|
|
167761
|
+
$('div', { className: 'actions' }, [save, status]),
|
|
167762
|
+
])))
|
|
167763
|
+
row.after(editRow)
|
|
167764
|
+
}
|
|
167765
|
+
|
|
167766
|
+
table.append(row)
|
|
167767
|
+
}
|
|
167768
|
+
|
|
167769
|
+
holder.append(table)
|
|
167770
|
+
}
|
|
167771
|
+
|
|
167772
|
+
// --------------------------------------------------------------
|
|
167773
|
+
// Create a new user.
|
|
167774
|
+
|
|
167775
|
+
const username = $('input', { placeholder: 'username', spellcheck: false })
|
|
167776
|
+
const password = $('input', { type: 'password', placeholder: 'password', spellcheck: false })
|
|
167777
|
+
const groups = groupBoxes(data.groups, [])
|
|
167778
|
+
const status = $('span', { className: 'status' })
|
|
167779
|
+
const create = $('button', { className: 'primary', textContent: 'Create user' })
|
|
167780
|
+
|
|
167781
|
+
create.onclick = async () => {
|
|
167782
|
+
create.disabled = true
|
|
167783
|
+
try {
|
|
167784
|
+
await api('/api/auth/create', {
|
|
167785
|
+
method: 'POST',
|
|
167786
|
+
body: JSON.stringify({
|
|
167787
|
+
pool: r.id,
|
|
167788
|
+
username: username.value,
|
|
167789
|
+
password: password.value,
|
|
167790
|
+
groups: groups.selected(),
|
|
167791
|
+
}),
|
|
167792
|
+
})
|
|
167793
|
+
main.innerHTML = ''
|
|
167794
|
+
renderResource(main)
|
|
167795
|
+
return
|
|
167796
|
+
} catch (error) {
|
|
167797
|
+
status.textContent = String(error.message ?? error)
|
|
167798
|
+
}
|
|
167799
|
+
create.disabled = false
|
|
167800
|
+
}
|
|
167801
|
+
|
|
167802
|
+
holder.append(
|
|
167803
|
+
$('h3', {}, 'Create user'),
|
|
167804
|
+
$('div', { className: 'config-form' }, [
|
|
167805
|
+
$('label', { className: 'field' }, [$('span', { className: 'name' }, 'username'), username]),
|
|
167806
|
+
$('label', { className: 'field' }, [$('span', { className: 'name' }, 'password'), password]),
|
|
167807
|
+
$('label', { className: 'field' }, [$('span', { className: 'name' }, 'groups'), groups.row]),
|
|
167808
|
+
$('div', { className: 'actions' }, [create, status]),
|
|
167809
|
+
]),
|
|
167810
|
+
)
|
|
167811
|
+
} catch (error) {
|
|
167812
|
+
holder.innerHTML = ''
|
|
167813
|
+
holder.append($('pre', { className: 'result error' }, String(error.message ?? error)))
|
|
167814
|
+
}
|
|
167815
|
+
}
|
|
167816
|
+
|
|
167460
167817
|
const renderResource = main => {
|
|
167461
167818
|
const r = view.resource
|
|
167462
167819
|
const back = $('button', { className: 'back' }, '\u2190 ' + groupTitle(r.kind))
|
|
@@ -167480,6 +167837,11 @@ const renderResource = main => {
|
|
|
167480
167837
|
if (r.kind === 'cache') return cachePanel(main, r)
|
|
167481
167838
|
if (r.kind === 'store') return storePanel(main, r)
|
|
167482
167839
|
if (r.kind === 'config') return configPanel(main)
|
|
167840
|
+
if (r.kind === 'auth') return authPanel(main, r)
|
|
167841
|
+
if (r.kind === 'worker') {
|
|
167842
|
+
cleanupPanel = attachLogFeed(main, 'worker')
|
|
167843
|
+
return
|
|
167844
|
+
}
|
|
167483
167845
|
if (r.kind === 'route' || r.kind === 'site') {
|
|
167484
167846
|
const url = r.url ?? r.detail
|
|
167485
167847
|
main.append($('p', {}, $('a', { href: url, target: '_blank', style: 'color: var(--accent)' }, url)))
|
|
@@ -167513,6 +167875,13 @@ const renderList = main => {
|
|
|
167513
167875
|
return emailPanel(main)
|
|
167514
167876
|
}
|
|
167515
167877
|
|
|
167878
|
+
// The worker page streams the bundle worker output directly,
|
|
167879
|
+
// instead of listing its single resource.
|
|
167880
|
+
if (view.kind === 'worker') {
|
|
167881
|
+
cleanupPanel = attachLogFeed(main, 'worker')
|
|
167882
|
+
return
|
|
167883
|
+
}
|
|
167884
|
+
|
|
167516
167885
|
const matches = r => {
|
|
167517
167886
|
if (filter.stack && r.stack !== filter.stack) return false
|
|
167518
167887
|
if (!filter.query) return true
|
|
@@ -167600,7 +167969,7 @@ const render = () => {
|
|
|
167600
167969
|
const button = $('button', { className: view.kind === kind ? 'active' : '' }, [
|
|
167601
167970
|
icon(kind),
|
|
167602
167971
|
title,
|
|
167603
|
-
kind === 'email' ? '' : $('span', { className: 'count' }, String(count)),
|
|
167972
|
+
kind === 'email' || kind === 'worker' ? '' : $('span', { className: 'count' }, String(count)),
|
|
167604
167973
|
])
|
|
167605
167974
|
button.onclick = () => selectKind(kind)
|
|
167606
167975
|
nav.append(button)
|
|
@@ -167861,6 +168230,36 @@ var createDashboardServer = (props) => {
|
|
|
167861
168230
|
if (url.pathname === "/api/emails") {
|
|
167862
168231
|
return { status: 200, body: JSON.stringify({ emails: props.getEmails?.() ?? [] }) };
|
|
167863
168232
|
}
|
|
168233
|
+
if (url.pathname.startsWith("/api/auth") && props.auth) {
|
|
168234
|
+
const auth2 = props.auth;
|
|
168235
|
+
try {
|
|
168236
|
+
if (url.pathname === "/api/auth" && req.method === "GET") {
|
|
168237
|
+
const pool = url.searchParams.get("pool") ?? "";
|
|
168238
|
+
return {
|
|
168239
|
+
status: 200,
|
|
168240
|
+
body: JSON.stringify({
|
|
168241
|
+
...auth2.describePool(pool),
|
|
168242
|
+
users: await auth2.listUsers(pool)
|
|
168243
|
+
})
|
|
168244
|
+
};
|
|
168245
|
+
}
|
|
168246
|
+
if (url.pathname === "/api/auth/create" && req.method === "POST") {
|
|
168247
|
+
const { pool, username, password: password2, groups } = JSON.parse((await readBody3(req)).toString() || "{}");
|
|
168248
|
+
await auth2.createUser(pool, { username, password: password2, groups: groups ?? [] });
|
|
168249
|
+
return { status: 200, body: JSON.stringify({ ok: true }) };
|
|
168250
|
+
}
|
|
168251
|
+
if (url.pathname === "/api/auth/update" && req.method === "POST") {
|
|
168252
|
+
const { pool, username, password: password2, groups } = JSON.parse((await readBody3(req)).toString() || "{}");
|
|
168253
|
+
await auth2.updateUser(pool, { username, password: password2 || undefined, groups: groups ?? [] });
|
|
168254
|
+
return { status: 200, body: JSON.stringify({ ok: true }) };
|
|
168255
|
+
}
|
|
168256
|
+
} catch (error3) {
|
|
168257
|
+
return {
|
|
168258
|
+
status: 400,
|
|
168259
|
+
body: JSON.stringify({ error: error3 instanceof Error ? error3.message : String(error3) })
|
|
168260
|
+
};
|
|
168261
|
+
}
|
|
168262
|
+
}
|
|
167864
168263
|
if (url.pathname === "/api/config") {
|
|
167865
168264
|
if (req.method === "PUT") {
|
|
167866
168265
|
const values2 = JSON.parse((await readBody3(req)).toString() || "{}");
|
|
@@ -168245,7 +168644,21 @@ var startDev = async (props) => {
|
|
|
168245
168644
|
workspace = await loadWorkspace3(directories.root);
|
|
168246
168645
|
await buildAll();
|
|
168247
168646
|
});
|
|
168248
|
-
const
|
|
168647
|
+
const emitWorkerLine = (line, error3 = false) => {
|
|
168648
|
+
dev.events.emit("worker", { date: Date.now(), line, error: error3 });
|
|
168649
|
+
};
|
|
168650
|
+
const worker = createBundleWorker({
|
|
168651
|
+
buildDir,
|
|
168652
|
+
env: env4,
|
|
168653
|
+
functionName: bundleName,
|
|
168654
|
+
onOutput: (line, stream2) => emitWorkerLine(line, stream2 === "stderr")
|
|
168655
|
+
});
|
|
168656
|
+
dev.resources.push({
|
|
168657
|
+
kind: "worker",
|
|
168658
|
+
id: "bundle",
|
|
168659
|
+
channel: "worker",
|
|
168660
|
+
detail: "The output & errors of the local bundle worker"
|
|
168661
|
+
});
|
|
168249
168662
|
let dirty = false;
|
|
168250
168663
|
let fresh;
|
|
168251
168664
|
let restartNeeded = false;
|
|
@@ -168321,7 +168734,13 @@ var startDev = async (props) => {
|
|
|
168321
168734
|
routers.push(await startDevRouter({
|
|
168322
168735
|
routes: dev.routes.filter((route) => route.routerId === id),
|
|
168323
168736
|
port,
|
|
168324
|
-
dispatch
|
|
168737
|
+
dispatch,
|
|
168738
|
+
onError(error3, routeKey) {
|
|
168739
|
+
const detail = error3 instanceof Error ? error3.stack ?? error3.message : String(error3);
|
|
168740
|
+
process.stderr.write(`Route ${routeKey} failed: ${detail}
|
|
168741
|
+
`);
|
|
168742
|
+
emitWorkerLine(`Route ${routeKey} failed: ${detail}`, true);
|
|
168743
|
+
}
|
|
168325
168744
|
}));
|
|
168326
168745
|
}
|
|
168327
168746
|
const dashboardPort = props.port;
|
|
@@ -168340,6 +168759,10 @@ var startDev = async (props) => {
|
|
|
168340
168759
|
configFile: join54(directories.output, "local", "config.json"),
|
|
168341
168760
|
getEmails: () => props.pool.peek("shim:ses-email")?.server.list() ?? [],
|
|
168342
168761
|
configPulled: Object.keys(props.pool.peek("config:pull") ?? {}),
|
|
168762
|
+
auth: createAuthAdmin({
|
|
168763
|
+
appConfig,
|
|
168764
|
+
resolvedPools: () => props.pool.peek("auth:pull")
|
|
168765
|
+
}),
|
|
168343
168766
|
events: dev.events
|
|
168344
168767
|
});
|
|
168345
168768
|
dashboard.connect(dispatch);
|
package/dist/handlers/bundle.js
CHANGED
|
@@ -452,7 +452,9 @@ var createBundle = (handlers) => {
|
|
|
452
452
|
}
|
|
453
453
|
throw new Error("Unknown bundle route: " + match2.key);
|
|
454
454
|
}
|
|
455
|
-
|
|
455
|
+
if (process.env.AWSLESS_ENV !== "local") {
|
|
456
|
+
console.trace(`Bundle route: ${match2.key}`);
|
|
457
|
+
}
|
|
456
458
|
process.env.AWSLESS_ROUTE = match2.key;
|
|
457
459
|
return withBundleRouteContext(match2.key, internalInvoke, async () => {
|
|
458
460
|
const handle = await load();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/cli",
|
|
3
|
-
"version": "0.0.46-local.
|
|
3
|
+
"version": "0.0.46-local.47",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -38,19 +38,19 @@
|
|
|
38
38
|
"@opensearch-project/opensearch": "^2.13.0",
|
|
39
39
|
"rolldown": "1.2.1",
|
|
40
40
|
"vitest": "4.1.10",
|
|
41
|
-
"@awsless/
|
|
42
|
-
"@awsless/
|
|
41
|
+
"@awsless/ts-file-cache": "^0.0.16",
|
|
42
|
+
"@awsless/dynamodb-server": "^0.1.8"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
+
"@awsless/dynamodb": "^0.3.22",
|
|
45
46
|
"@awsless/big-float": "^0.1.7",
|
|
47
|
+
"@awsless/lambda": "^0.0.47",
|
|
48
|
+
"@awsless/validate": "^0.1.7",
|
|
46
49
|
"@awsless/s3": "^0.0.22",
|
|
47
50
|
"@awsless/duration": "^0.0.4",
|
|
48
|
-
"@awsless/
|
|
49
|
-
"@awsless/lambda": "^0.0.47",
|
|
50
|
-
"@awsless/dynamodb": "^0.3.22",
|
|
51
|
+
"@awsless/json": "^0.0.11",
|
|
51
52
|
"@awsless/weak-cache": "^0.0.1",
|
|
52
|
-
"awsless": "^0.0.15-local.11"
|
|
53
|
-
"@awsless/json": "^0.0.11"
|
|
53
|
+
"awsless": "^0.0.15-local.11"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@aws-sdk/client-cloudformation": "^3.369.0",
|
|
@@ -121,24 +121,24 @@
|
|
|
121
121
|
"zod": "^3.24.2",
|
|
122
122
|
"zod-to-json-schema": "^3.24.3",
|
|
123
123
|
"@awsless/big-float": "^0.1.7",
|
|
124
|
-
"@awsless/cloudwatch": "^0.0.1",
|
|
125
124
|
"@awsless/clui": "^0.0.9",
|
|
126
125
|
"@awsless/duration": "^0.0.4",
|
|
126
|
+
"@awsless/cloudwatch": "^0.0.1",
|
|
127
|
+
"@awsless/iot": "^0.0.5",
|
|
127
128
|
"@awsless/json": "^0.0.11",
|
|
129
|
+
"@awsless/dynamodb": "^0.3.22",
|
|
130
|
+
"@awsless/open-search": "^0.0.26",
|
|
128
131
|
"@awsless/lambda": "^0.0.47",
|
|
132
|
+
"@awsless/s3": "^0.0.22",
|
|
129
133
|
"@awsless/redis": "^0.1.13",
|
|
130
134
|
"@awsless/size": "^0.0.2",
|
|
131
|
-
"@awsless/iot": "^0.0.5",
|
|
132
|
-
"@awsless/open-search": "^0.0.26",
|
|
133
|
-
"@awsless/s3": "^0.0.22",
|
|
134
|
-
"@awsless/dynamodb": "^0.3.22",
|
|
135
135
|
"@awsless/sns": "^0.0.11",
|
|
136
136
|
"@awsless/scheduler": "^0.0.5",
|
|
137
137
|
"@awsless/sqs": "^0.0.24",
|
|
138
138
|
"@awsless/validate": "^0.1.7",
|
|
139
|
+
"@awsless/ssm": "^0.0.8",
|
|
139
140
|
"@awsless/weak-cache": "^0.0.1",
|
|
140
|
-
"awsless": "^0.0.15-local.11"
|
|
141
|
-
"@awsless/ssm": "^0.0.8"
|
|
141
|
+
"awsless": "^0.0.15-local.11"
|
|
142
142
|
},
|
|
143
143
|
"scripts": {
|
|
144
144
|
"test": "bun cli/build-handlers.ts && pnpm vitest",
|