@easy-cms/core 0.36.1 → 0.37.1
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/index.d.ts +12 -1
- package/dist/index.js +23 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -194,11 +194,16 @@ declare class Auth {
|
|
|
194
194
|
private get config();
|
|
195
195
|
/** Checks credentials and starts a session. Throws `UnauthorizedError` or `TooManyRequestsError`. */
|
|
196
196
|
login(args: LoginArgs): Promise<Session>;
|
|
197
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Creates the first admin. Only works while there are no users, and with `auth.setupCode`
|
|
199
|
+
* (`EASY_CMS_SETUP_CODE`) only with that code.
|
|
200
|
+
*/
|
|
198
201
|
registerFirstUser(args: {
|
|
199
202
|
email: string;
|
|
200
203
|
password: string;
|
|
201
204
|
name?: string;
|
|
205
|
+
setupCode?: string;
|
|
206
|
+
ip?: string | undefined;
|
|
202
207
|
}): Promise<Session>;
|
|
203
208
|
hasUsers(): Promise<boolean>;
|
|
204
209
|
/** Ends the session for a signed token. Unknown tokens are ignored. */
|
|
@@ -2233,6 +2238,12 @@ interface AuthConfig {
|
|
|
2233
2238
|
* everyone else signs in with `providers`. Default `true`.
|
|
2234
2239
|
*/
|
|
2235
2240
|
readonly password?: boolean;
|
|
2241
|
+
/**
|
|
2242
|
+
* A code the first admin must enter to create their account, so nobody else can claim a
|
|
2243
|
+
* freshly deployed site. Default: the `EASY_CMS_SETUP_CODE` environment variable; without it,
|
|
2244
|
+
* no code is asked.
|
|
2245
|
+
*/
|
|
2246
|
+
readonly setupCode?: string;
|
|
2236
2247
|
/** Your own text for the password emails, e.g. in your brand's voice. Default: English or Thai. */
|
|
2237
2248
|
readonly emails?: {
|
|
2238
2249
|
readonly resetPassword?: PasswordEmailFn;
|
package/dist/index.js
CHANGED
|
@@ -1515,9 +1515,21 @@ var Auth = class {
|
|
|
1515
1515
|
await this.cms.audit.record({ action: "login", target: "auth", user: session.user });
|
|
1516
1516
|
return session;
|
|
1517
1517
|
}
|
|
1518
|
-
/**
|
|
1518
|
+
/**
|
|
1519
|
+
* Creates the first admin. Only works while there are no users, and with `auth.setupCode`
|
|
1520
|
+
* (`EASY_CMS_SETUP_CODE`) only with that code.
|
|
1521
|
+
*/
|
|
1519
1522
|
async registerFirstUser(args) {
|
|
1520
1523
|
if (await this.hasUsers()) throw new ForbiddenError("An admin already exists");
|
|
1524
|
+
const code = this.config.auth.setupCode;
|
|
1525
|
+
if (code) {
|
|
1526
|
+
const key2 = `setup|${args.ip ?? ""}`;
|
|
1527
|
+
await this.checkRateLimit(key2);
|
|
1528
|
+
if (!safeEqual(String(args.setupCode ?? ""), code)) {
|
|
1529
|
+
await this.recordFailure(key2);
|
|
1530
|
+
throw new ValidationError(USERS, [{ field: "setupCode", message: "is not the setup code" }]);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1521
1533
|
const user = await this.cms.create(USERS, {
|
|
1522
1534
|
email: args.email,
|
|
1523
1535
|
password: args.password,
|
|
@@ -4049,6 +4061,8 @@ function validateAuth(config, add) {
|
|
|
4049
4061
|
add("auth.rbac", "must be true or false");
|
|
4050
4062
|
if (auth.password !== void 0 && typeof auth.password !== "boolean")
|
|
4051
4063
|
add("auth.password", "must be true or false");
|
|
4064
|
+
if (auth.setupCode !== void 0 && typeof auth.setupCode !== "string")
|
|
4065
|
+
add("auth.setupCode", "must be a string");
|
|
4052
4066
|
const providers = auth.providers;
|
|
4053
4067
|
if (providers !== void 0) {
|
|
4054
4068
|
if (!Array.isArray(providers)) {
|
|
@@ -4832,6 +4846,7 @@ async function resolveConfig(input) {
|
|
|
4832
4846
|
providers: config.auth?.providers ?? [],
|
|
4833
4847
|
allowSignUp: config.auth?.allowSignUp ?? { domains: [] },
|
|
4834
4848
|
password: config.auth?.password !== false,
|
|
4849
|
+
setupCode: config.auth?.setupCode ?? process.env.EASY_CMS_SETUP_CODE ?? "",
|
|
4835
4850
|
tokenExpiration: config.auth?.tokenExpiration ?? DEFAULT_TOKEN_EXPIRATION,
|
|
4836
4851
|
maxLoginAttempts: config.auth?.maxLoginAttempts ?? 5,
|
|
4837
4852
|
lockWindow: config.auth?.lockWindow ?? 15 * 60,
|
|
@@ -7611,7 +7626,7 @@ async function widgets(cms, user) {
|
|
|
7611
7626
|
}
|
|
7612
7627
|
|
|
7613
7628
|
// src/version.ts
|
|
7614
|
-
var VERSION = true ? "0.
|
|
7629
|
+
var VERSION = true ? "0.37.1" : "0.0.0-dev";
|
|
7615
7630
|
|
|
7616
7631
|
// src/rest/admin-status.ts
|
|
7617
7632
|
var DAY2 = 864e5;
|
|
@@ -8004,7 +8019,9 @@ async function route(cms, ctx, method, segments, options) {
|
|
|
8004
8019
|
passwordReset: cms.auth.canSendPasswordLinks(ctx.url.origin),
|
|
8005
8020
|
// Buttons to sign in with outside accounts; `password: false`: only admins use one.
|
|
8006
8021
|
providers: cms.auth.sso.providers(),
|
|
8007
|
-
password: cms.config.auth.password
|
|
8022
|
+
password: cms.config.auth.password,
|
|
8023
|
+
// The first admin needs the setup code (`EASY_CMS_SETUP_CODE`).
|
|
8024
|
+
setupCode: cms.config.auth.setupCode !== ""
|
|
8008
8025
|
}
|
|
8009
8026
|
};
|
|
8010
8027
|
// Forgot password: the same answer whether or not the email has an account.
|
|
@@ -8045,7 +8062,9 @@ async function route(cms, ctx, method, segments, options) {
|
|
|
8045
8062
|
const session = await cms.auth.registerFirstUser({
|
|
8046
8063
|
email: String(body.email ?? ""),
|
|
8047
8064
|
password: String(body.password ?? ""),
|
|
8048
|
-
...typeof body.name === "string" ? { name: body.name } : {}
|
|
8065
|
+
...typeof body.name === "string" ? { name: body.name } : {},
|
|
8066
|
+
...typeof body.setupCode === "string" ? { setupCode: body.setupCode } : {},
|
|
8067
|
+
ip: options.getClientIp?.(ctx.request)
|
|
8049
8068
|
});
|
|
8050
8069
|
setSessionCookies(cms, ctx, session);
|
|
8051
8070
|
return {
|