strapi-identity 0.4.1 → 0.5.0
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/admin/{AdminReset-BiWQDTRv.js → AdminReset-BoWx0F06.js} +1 -1
- package/dist/admin/{AdminReset-DOmsyqwQ.mjs → AdminReset-D4NNnBDS.mjs} +1 -1
- package/dist/admin/{ProfileToggle-BUqs_hxZ.js → ProfileToggle-DtjyJRWN.js} +1 -1
- package/dist/admin/{ProfileToggle-k0d-caPC.mjs → ProfileToggle-NJZgrDT_.mjs} +1 -1
- package/dist/admin/{SettingsPage-DVVkN1xw.js → SettingsPage-BXl7gVGV.js} +1 -1
- package/dist/admin/{SettingsPage-Dm_llkYv.mjs → SettingsPage-CZuOMYvG.mjs} +1 -1
- package/dist/admin/{index-B9P8S4CX.js → index-BeqHh5Gz.js} +22 -15
- package/dist/admin/{index-DpIJdETG.mjs → index-CKG2ZxYT.mjs} +22 -15
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/ConfirmModal/ConfirmModal.d.ts +9 -0
- package/dist/admin/src/components/ConfirmModal/index.d.ts +1 -0
- package/dist/admin/src/components/EmailOTPModal/EmailOTPModal.d.ts +8 -0
- package/dist/admin/src/components/Initializer.d.ts +5 -0
- package/dist/admin/src/components/InputOTP.d.ts +11 -0
- package/dist/admin/src/components/RemoveModal/RemoveModal.d.ts +6 -0
- package/dist/admin/src/components/RemoveModal/index.d.ts +1 -0
- package/dist/admin/src/components/WarningAlert/WarningAlert.d.ts +10 -0
- package/dist/admin/src/components/WarningAlert/index.d.ts +1 -0
- package/dist/admin/src/injection/AdminReset.d.ts +4 -0
- package/dist/admin/src/injection/ProfileToggle.d.ts +2 -0
- package/dist/admin/src/pages/EnforcedPage.d.ts +13 -0
- package/dist/admin/src/pluginId.d.ts +1 -0
- package/dist/admin/src/public/VerifyPage.d.ts +12 -0
- package/dist/admin/src/settings/SettingsPage.d.ts +1 -0
- package/dist/admin/src/utils/getTranslation.d.ts +2 -0
- package/dist/admin/src/utils/tokenHelpers.d.ts +12 -0
- package/dist/server/index.js +75 -49
- package/dist/server/index.mjs +75 -49
- package/dist/server/src/bootstrap.d.ts +3 -0
- package/dist/server/src/config/index.d.ts +3 -0
- package/dist/server/src/content-types/config/index.d.ts +72 -0
- package/dist/server/src/content-types/config/schema.json.d.ts +72 -0
- package/dist/server/src/content-types/email-otp/index.d.ts +48 -0
- package/dist/server/src/content-types/email-otp/schema.json.d.ts +48 -0
- package/dist/server/src/content-types/index.d.ts +3 -0
- package/dist/server/src/content-types/mfa/index.d.ts +55 -0
- package/dist/server/src/content-types/mfa/schema.json.d.ts +55 -0
- package/dist/server/src/content-types/temp-mfa/index.d.ts +35 -0
- package/dist/server/src/content-types/temp-mfa/schema.json.d.ts +35 -0
- package/dist/server/src/controllers/admin.d.ts +4 -0
- package/dist/server/src/controllers/config.d.ts +4 -0
- package/dist/server/src/controllers/controller.d.ts +8 -0
- package/dist/server/src/controllers/index.d.ts +3 -0
- package/dist/server/src/destroy.d.ts +3 -0
- package/dist/server/src/middlewares/index.d.ts +3 -0
- package/dist/server/src/policies/has-mfa.d.ts +3 -0
- package/dist/server/src/policies/index.d.ts +3 -0
- package/dist/server/src/register.d.ts +3 -0
- package/dist/server/src/routes/admin/admin.json.d.ts +35 -0
- package/dist/server/src/routes/admin/config.json.d.ts +50 -0
- package/dist/server/src/routes/admin/index.d.ts +3 -0
- package/dist/server/src/routes/admin/mfa.json.d.ts +94 -0
- package/dist/server/src/routes/index.d.ts +3 -0
- package/dist/server/src/services/admin.d.ts +11 -0
- package/dist/server/src/services/config.d.ts +57 -0
- package/dist/server/src/services/email.d.ts +8 -0
- package/dist/server/src/services/index.d.ts +3 -0
- package/dist/server/src/services/mfa.d.ts +82 -0
- package/package.json +6 -5
package/dist/server/index.js
CHANGED
|
@@ -9650,7 +9650,7 @@ const replaceLogin = (route2, secret2, domain) => {
|
|
|
9650
9650
|
await strapi.service("plugin::strapi-identity.email").send(adminUser.email, otp);
|
|
9651
9651
|
}
|
|
9652
9652
|
} catch (err) {
|
|
9653
|
-
|
|
9653
|
+
strapi.log.error("Error sending login email OTP");
|
|
9654
9654
|
}
|
|
9655
9655
|
}
|
|
9656
9656
|
ctx.res.removeHeader("set-cookie");
|
|
@@ -9663,7 +9663,8 @@ const replaceLogin = (route2, secret2, domain) => {
|
|
|
9663
9663
|
};
|
|
9664
9664
|
const newToken = jwt.sign(newPayload, secret2, { expiresIn: "5m" });
|
|
9665
9665
|
const expires = new Date(Date.now() + 5 * 60 * 1e3);
|
|
9666
|
-
const
|
|
9666
|
+
const secure = strapi.config.get("admin.auth.cookie.secure") ?? process.env.NODE_ENV === "production";
|
|
9667
|
+
const opt = { domain, httpOnly: true, overwrite: true, secure, expires };
|
|
9667
9668
|
ctx.cookies.set("strapi_admin_mfa", newToken, opt);
|
|
9668
9669
|
ctx.body.data = { data: {}, error: null };
|
|
9669
9670
|
});
|
|
@@ -9709,7 +9710,6 @@ const registerMiddlewares = (server) => {
|
|
|
9709
9710
|
"/admin/users/me",
|
|
9710
9711
|
"/strapi-identity/status",
|
|
9711
9712
|
"/strapi-identity/config",
|
|
9712
|
-
"/strapi-identity/config/enabled",
|
|
9713
9713
|
"/strapi-identity/enable",
|
|
9714
9714
|
"/strapi-identity/setup",
|
|
9715
9715
|
"/strapi-identity/enable-email",
|
|
@@ -9717,7 +9717,6 @@ const registerMiddlewares = (server) => {
|
|
|
9717
9717
|
];
|
|
9718
9718
|
const isAllowed = allowedPaths.includes(ctx.path) || // Static assets (JS, CSS, images, fonts, sourcemaps)
|
|
9719
9719
|
/\.(mjs|js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot|map)(\?.*)?$/.test(ctx.path) || ctx.path.startsWith("/admin/@") || ctx.path.startsWith("/admin/src/");
|
|
9720
|
-
if (!isAllowed) console.log(ctx.path);
|
|
9721
9720
|
if (!isAllowed) {
|
|
9722
9721
|
if (ctx.accepts("html") && ctx.path.startsWith("/admin")) {
|
|
9723
9722
|
ctx.redirect("/admin/strapi-identity/enforced");
|
|
@@ -9844,7 +9843,7 @@ const config$2 = ({ strapi: strapi2 }) => ({
|
|
|
9844
9843
|
ctx.status = 200;
|
|
9845
9844
|
ctx.body = { data: enabled, error: null };
|
|
9846
9845
|
} catch (error) {
|
|
9847
|
-
|
|
9846
|
+
strapi2.log.error("Error checking if Strapi Identity is enabled");
|
|
9848
9847
|
ctx.status = 500;
|
|
9849
9848
|
ctx.body = { data: null, error: "Server Error" };
|
|
9850
9849
|
}
|
|
@@ -9855,18 +9854,7 @@ const config$2 = ({ strapi: strapi2 }) => ({
|
|
|
9855
9854
|
ctx.status = 200;
|
|
9856
9855
|
ctx.body = { data: config2, error: null };
|
|
9857
9856
|
} catch (error) {
|
|
9858
|
-
|
|
9859
|
-
ctx.status = 500;
|
|
9860
|
-
ctx.body = { data: null, error: "Server Error" };
|
|
9861
|
-
}
|
|
9862
|
-
},
|
|
9863
|
-
async getEmailStatus(ctx) {
|
|
9864
|
-
try {
|
|
9865
|
-
const emailService = strapi2.config.get("plugin::email");
|
|
9866
|
-
ctx.status = 200;
|
|
9867
|
-
ctx.body = { data: emailService, error: null };
|
|
9868
|
-
} catch (error) {
|
|
9869
|
-
console.log("Error getting email status:", error);
|
|
9857
|
+
strapi2.log.error("Error getting config");
|
|
9870
9858
|
ctx.status = 500;
|
|
9871
9859
|
ctx.body = { data: null, error: "Server Error" };
|
|
9872
9860
|
}
|
|
@@ -9878,7 +9866,7 @@ const config$2 = ({ strapi: strapi2 }) => ({
|
|
|
9878
9866
|
ctx.status = 200;
|
|
9879
9867
|
ctx.body = { data: updatedConfig, error: null };
|
|
9880
9868
|
} catch (error) {
|
|
9881
|
-
|
|
9869
|
+
strapi2.log.error("Error updating config");
|
|
9882
9870
|
ctx.status = 500;
|
|
9883
9871
|
ctx.body = { data: null, error: "Server Error" };
|
|
9884
9872
|
}
|
|
@@ -9930,6 +9918,18 @@ const buildCookieOptionsWithExpiry = (type, absoluteExpiresAtISO, secureRequest)
|
|
|
9930
9918
|
return { ...base, expires: chosen, maxAge: Math.max(0, chosen.getTime() - now) };
|
|
9931
9919
|
};
|
|
9932
9920
|
const controller = ({ strapi: strapi2 }) => ({
|
|
9921
|
+
async verifyInfo(ctx) {
|
|
9922
|
+
const secret2 = strapi2.config.get("admin.auth.secret");
|
|
9923
|
+
const token = ctx.cookies.get("strapi_admin_mfa");
|
|
9924
|
+
try {
|
|
9925
|
+
const payload = jwt.verify(token, secret2);
|
|
9926
|
+
ctx.status = 200;
|
|
9927
|
+
ctx.body = { data: { mfaType: payload.mfaType || null }, error: null };
|
|
9928
|
+
} catch {
|
|
9929
|
+
ctx.status = 401;
|
|
9930
|
+
ctx.body = { data: null, error: "Invalid or expired MFA session" };
|
|
9931
|
+
}
|
|
9932
|
+
},
|
|
9933
9933
|
async verify(ctx) {
|
|
9934
9934
|
const sessionManager = strapi2.sessionManager;
|
|
9935
9935
|
const secret2 = strapi2.config.get("admin.auth.secret");
|
|
@@ -9954,19 +9954,20 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
9954
9954
|
).generateRefreshToken(payload.userId, payload.deviceId, {
|
|
9955
9955
|
type: payload.rememberMe ? "refresh" : "session"
|
|
9956
9956
|
});
|
|
9957
|
+
const secure = strapi2.config.get("admin.auth.cookie.secure") ?? process.env.NODE_ENV === "production";
|
|
9957
9958
|
ctx.cookies.set(
|
|
9958
9959
|
"strapi_admin_refresh",
|
|
9959
9960
|
refreshToken,
|
|
9960
9961
|
buildCookieOptionsWithExpiry(
|
|
9961
9962
|
payload.rememberMe ? "refresh" : "session",
|
|
9962
9963
|
absoluteExpiresAt,
|
|
9963
|
-
|
|
9964
|
+
secure
|
|
9964
9965
|
)
|
|
9965
9966
|
);
|
|
9966
9967
|
const accessResult = await sessionManager("admin").generateAccessToken(refreshToken);
|
|
9967
9968
|
const { token: accessToken } = accessResult;
|
|
9968
9969
|
const domain = strapi2.config.get("admin.auth.domain");
|
|
9969
|
-
const opt = { httpOnly: false, secure
|
|
9970
|
+
const opt = { httpOnly: false, secure, overwrite: true, domain };
|
|
9970
9971
|
ctx.cookies.set("jwtToken", accessToken, opt);
|
|
9971
9972
|
ctx.cookies.set("strapi_admin_mfa", null, { expires: /* @__PURE__ */ new Date(0) });
|
|
9972
9973
|
ctx.status = 200;
|
|
@@ -9975,7 +9976,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
9975
9976
|
error: null
|
|
9976
9977
|
};
|
|
9977
9978
|
} catch (error) {
|
|
9978
|
-
|
|
9979
|
+
strapi2.log.error("Error verifying MFA code");
|
|
9979
9980
|
ctx.status = 500;
|
|
9980
9981
|
ctx.body = { data: null, error: "Server Error" };
|
|
9981
9982
|
}
|
|
@@ -9998,7 +9999,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
9998
9999
|
ctx.body = { data: { message: "MFA disabled" }, error: null };
|
|
9999
10000
|
}
|
|
10000
10001
|
} catch (error) {
|
|
10001
|
-
|
|
10002
|
+
strapi2.log.error("Error enabling/disabling MFA");
|
|
10002
10003
|
ctx.status = 500;
|
|
10003
10004
|
ctx.body = { data: null, error: "Failed to update MFA" };
|
|
10004
10005
|
}
|
|
@@ -10043,7 +10044,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10043
10044
|
ctx.status = 200;
|
|
10044
10045
|
ctx.body = { data: { message: "MFA disabled" }, error: null };
|
|
10045
10046
|
} catch (error) {
|
|
10046
|
-
|
|
10047
|
+
strapi2.log.error("Error disabling MFA");
|
|
10047
10048
|
ctx.status = 500;
|
|
10048
10049
|
ctx.body = { data: null, error: "Failed to disable MFA" };
|
|
10049
10050
|
}
|
|
@@ -10071,7 +10072,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10071
10072
|
ctx.status = 200;
|
|
10072
10073
|
ctx.body = { data: { message: "Verification email sent" }, error: null };
|
|
10073
10074
|
} catch (error) {
|
|
10074
|
-
|
|
10075
|
+
strapi2.log.error("Error initiating email MFA setup");
|
|
10075
10076
|
ctx.status = 500;
|
|
10076
10077
|
ctx.body = { data: null, error: "Failed to initiate email MFA setup" };
|
|
10077
10078
|
}
|
|
@@ -10091,7 +10092,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10091
10092
|
ctx.status = 200;
|
|
10092
10093
|
ctx.body = { data: { message: "Email OTP enabled" }, error: null };
|
|
10093
10094
|
} catch (error) {
|
|
10094
|
-
|
|
10095
|
+
strapi2.log.error("Error completing email MFA setup");
|
|
10095
10096
|
ctx.status = 500;
|
|
10096
10097
|
ctx.body = { data: null, error: "Failed to enable email MFA" };
|
|
10097
10098
|
}
|
|
@@ -10112,7 +10113,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10112
10113
|
ctx.status = 200;
|
|
10113
10114
|
ctx.body = { data: { message: "Verification email sent" }, error: null };
|
|
10114
10115
|
} catch (error) {
|
|
10115
|
-
|
|
10116
|
+
strapi2.log.error("Error sending disable email OTP");
|
|
10116
10117
|
ctx.status = 500;
|
|
10117
10118
|
ctx.body = { data: null, error: "Failed to send verification email" };
|
|
10118
10119
|
}
|
|
@@ -10140,7 +10141,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10140
10141
|
ctx.status = 200;
|
|
10141
10142
|
ctx.body = { data: { message: "Verification email resent" }, error: null };
|
|
10142
10143
|
} catch (error) {
|
|
10143
|
-
|
|
10144
|
+
strapi2.log.error("Error resending login email OTP");
|
|
10144
10145
|
ctx.status = 500;
|
|
10145
10146
|
ctx.body = { data: null, error: "Failed to resend verification email" };
|
|
10146
10147
|
}
|
|
@@ -10226,35 +10227,40 @@ const config$1 = [
|
|
|
10226
10227
|
pluginName: "strapi-identity",
|
|
10227
10228
|
type: "content-api"
|
|
10228
10229
|
},
|
|
10229
|
-
config: {}
|
|
10230
|
-
},
|
|
10231
|
-
{
|
|
10232
|
-
method: "GET",
|
|
10233
|
-
path: "/config",
|
|
10234
|
-
handler: "config.getConfig",
|
|
10235
|
-
info: {
|
|
10236
|
-
apiName: "getConfig",
|
|
10237
|
-
pluginName: "strapi-identity",
|
|
10238
|
-
type: "content-api"
|
|
10239
|
-
},
|
|
10240
10230
|
config: {
|
|
10241
10231
|
policies: [
|
|
10242
|
-
"admin::isAuthenticatedAdmin"
|
|
10232
|
+
"admin::isAuthenticatedAdmin",
|
|
10233
|
+
{
|
|
10234
|
+
name: "admin::hasPermissions",
|
|
10235
|
+
config: {
|
|
10236
|
+
actions: [
|
|
10237
|
+
"plugin::strapi-identity.settings.read"
|
|
10238
|
+
]
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10243
10241
|
]
|
|
10244
10242
|
}
|
|
10245
10243
|
},
|
|
10246
10244
|
{
|
|
10247
10245
|
method: "GET",
|
|
10248
|
-
path: "/config
|
|
10249
|
-
handler: "config.
|
|
10246
|
+
path: "/config",
|
|
10247
|
+
handler: "config.getConfig",
|
|
10250
10248
|
info: {
|
|
10251
|
-
apiName: "
|
|
10249
|
+
apiName: "getConfig",
|
|
10252
10250
|
pluginName: "strapi-identity",
|
|
10253
10251
|
type: "content-api"
|
|
10254
10252
|
},
|
|
10255
10253
|
config: {
|
|
10256
10254
|
policies: [
|
|
10257
|
-
"admin::isAuthenticatedAdmin"
|
|
10255
|
+
"admin::isAuthenticatedAdmin",
|
|
10256
|
+
{
|
|
10257
|
+
name: "admin::hasPermissions",
|
|
10258
|
+
config: {
|
|
10259
|
+
actions: [
|
|
10260
|
+
"plugin::strapi-identity.settings.read"
|
|
10261
|
+
]
|
|
10262
|
+
}
|
|
10263
|
+
}
|
|
10258
10264
|
]
|
|
10259
10265
|
}
|
|
10260
10266
|
},
|
|
@@ -10283,6 +10289,22 @@ const config$1 = [
|
|
|
10283
10289
|
}
|
|
10284
10290
|
];
|
|
10285
10291
|
const mfa = [
|
|
10292
|
+
{
|
|
10293
|
+
method: "GET",
|
|
10294
|
+
path: "/verify/info",
|
|
10295
|
+
handler: "controller.verifyInfo",
|
|
10296
|
+
info: {
|
|
10297
|
+
apiName: "verifyInfo",
|
|
10298
|
+
pluginName: "strapi-identity",
|
|
10299
|
+
type: "content-api"
|
|
10300
|
+
},
|
|
10301
|
+
config: {
|
|
10302
|
+
auth: false,
|
|
10303
|
+
policies: [
|
|
10304
|
+
"has-mfa"
|
|
10305
|
+
]
|
|
10306
|
+
}
|
|
10307
|
+
},
|
|
10286
10308
|
{
|
|
10287
10309
|
method: "POST",
|
|
10288
10310
|
path: "/verify",
|
|
@@ -10296,6 +10318,9 @@ const mfa = [
|
|
|
10296
10318
|
auth: false,
|
|
10297
10319
|
policies: [
|
|
10298
10320
|
"has-mfa"
|
|
10321
|
+
],
|
|
10322
|
+
middlewares: [
|
|
10323
|
+
"admin::rateLimit"
|
|
10299
10324
|
]
|
|
10300
10325
|
}
|
|
10301
10326
|
},
|
|
@@ -10356,7 +10381,8 @@ const mfa = [
|
|
|
10356
10381
|
auth: false,
|
|
10357
10382
|
policies: [
|
|
10358
10383
|
"has-mfa"
|
|
10359
|
-
]
|
|
10384
|
+
],
|
|
10385
|
+
middlewares: []
|
|
10360
10386
|
}
|
|
10361
10387
|
},
|
|
10362
10388
|
{
|
|
@@ -10405,7 +10431,7 @@ const isEnabled$1 = (id) => {
|
|
|
10405
10431
|
try {
|
|
10406
10432
|
return mfaToken2.count({ where: { admin_user: { id }, enabled: true } }).then((count) => count > 0);
|
|
10407
10433
|
} catch (error) {
|
|
10408
|
-
|
|
10434
|
+
strapi.log.error("Error checking if 2FA is enabled for user");
|
|
10409
10435
|
return false;
|
|
10410
10436
|
}
|
|
10411
10437
|
};
|
|
@@ -10422,7 +10448,7 @@ const reset = async (id) => {
|
|
|
10422
10448
|
existingTemp ? mfaTemp2.delete({ documentId: existingTemp.documentId }) : null
|
|
10423
10449
|
]);
|
|
10424
10450
|
} catch (error) {
|
|
10425
|
-
|
|
10451
|
+
strapi.log.error("Error resetting 2FA for user");
|
|
10426
10452
|
throw new Error("Failed to reset 2FA for user");
|
|
10427
10453
|
}
|
|
10428
10454
|
};
|
|
@@ -10486,7 +10512,7 @@ const disableEmailMFAForAllUsers = async () => {
|
|
|
10486
10512
|
)
|
|
10487
10513
|
]);
|
|
10488
10514
|
} catch (err) {
|
|
10489
|
-
|
|
10515
|
+
strapi.log.error("Error disabling email MFA for all users");
|
|
10490
10516
|
}
|
|
10491
10517
|
};
|
|
10492
10518
|
const disableMFAForAllUsers = async () => {
|
|
@@ -10502,7 +10528,7 @@ const disableMFAForAllUsers = async () => {
|
|
|
10502
10528
|
...temps.map((temp) => tempDocument.delete({ documentId: temp.documentId }))
|
|
10503
10529
|
]);
|
|
10504
10530
|
} catch (err) {
|
|
10505
|
-
|
|
10531
|
+
strapi.log.error("Error disabling MFA for all users");
|
|
10506
10532
|
}
|
|
10507
10533
|
};
|
|
10508
10534
|
const checkUserByJWT = async (jwtToken) => {
|
|
@@ -10555,7 +10581,7 @@ const send = async (to, otp) => {
|
|
|
10555
10581
|
sendConfig.replyTo = config2.response_email;
|
|
10556
10582
|
}
|
|
10557
10583
|
return emailService.send(sendConfig).catch((error) => {
|
|
10558
|
-
|
|
10584
|
+
strapi.log.error("Error sending email");
|
|
10559
10585
|
});
|
|
10560
10586
|
};
|
|
10561
10587
|
const replaceTemplateVariables = (template, variables) => {
|
package/dist/server/index.mjs
CHANGED
|
@@ -9643,7 +9643,7 @@ const replaceLogin = (route2, secret2, domain) => {
|
|
|
9643
9643
|
await strapi.service("plugin::strapi-identity.email").send(adminUser.email, otp);
|
|
9644
9644
|
}
|
|
9645
9645
|
} catch (err) {
|
|
9646
|
-
|
|
9646
|
+
strapi.log.error("Error sending login email OTP");
|
|
9647
9647
|
}
|
|
9648
9648
|
}
|
|
9649
9649
|
ctx.res.removeHeader("set-cookie");
|
|
@@ -9656,7 +9656,8 @@ const replaceLogin = (route2, secret2, domain) => {
|
|
|
9656
9656
|
};
|
|
9657
9657
|
const newToken = jwt.sign(newPayload, secret2, { expiresIn: "5m" });
|
|
9658
9658
|
const expires = new Date(Date.now() + 5 * 60 * 1e3);
|
|
9659
|
-
const
|
|
9659
|
+
const secure = strapi.config.get("admin.auth.cookie.secure") ?? process.env.NODE_ENV === "production";
|
|
9660
|
+
const opt = { domain, httpOnly: true, overwrite: true, secure, expires };
|
|
9660
9661
|
ctx.cookies.set("strapi_admin_mfa", newToken, opt);
|
|
9661
9662
|
ctx.body.data = { data: {}, error: null };
|
|
9662
9663
|
});
|
|
@@ -9702,7 +9703,6 @@ const registerMiddlewares = (server) => {
|
|
|
9702
9703
|
"/admin/users/me",
|
|
9703
9704
|
"/strapi-identity/status",
|
|
9704
9705
|
"/strapi-identity/config",
|
|
9705
|
-
"/strapi-identity/config/enabled",
|
|
9706
9706
|
"/strapi-identity/enable",
|
|
9707
9707
|
"/strapi-identity/setup",
|
|
9708
9708
|
"/strapi-identity/enable-email",
|
|
@@ -9710,7 +9710,6 @@ const registerMiddlewares = (server) => {
|
|
|
9710
9710
|
];
|
|
9711
9711
|
const isAllowed = allowedPaths.includes(ctx.path) || // Static assets (JS, CSS, images, fonts, sourcemaps)
|
|
9712
9712
|
/\.(mjs|js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|eot|map)(\?.*)?$/.test(ctx.path) || ctx.path.startsWith("/admin/@") || ctx.path.startsWith("/admin/src/");
|
|
9713
|
-
if (!isAllowed) console.log(ctx.path);
|
|
9714
9713
|
if (!isAllowed) {
|
|
9715
9714
|
if (ctx.accepts("html") && ctx.path.startsWith("/admin")) {
|
|
9716
9715
|
ctx.redirect("/admin/strapi-identity/enforced");
|
|
@@ -9837,7 +9836,7 @@ const config$2 = ({ strapi: strapi2 }) => ({
|
|
|
9837
9836
|
ctx.status = 200;
|
|
9838
9837
|
ctx.body = { data: enabled, error: null };
|
|
9839
9838
|
} catch (error) {
|
|
9840
|
-
|
|
9839
|
+
strapi2.log.error("Error checking if Strapi Identity is enabled");
|
|
9841
9840
|
ctx.status = 500;
|
|
9842
9841
|
ctx.body = { data: null, error: "Server Error" };
|
|
9843
9842
|
}
|
|
@@ -9848,18 +9847,7 @@ const config$2 = ({ strapi: strapi2 }) => ({
|
|
|
9848
9847
|
ctx.status = 200;
|
|
9849
9848
|
ctx.body = { data: config2, error: null };
|
|
9850
9849
|
} catch (error) {
|
|
9851
|
-
|
|
9852
|
-
ctx.status = 500;
|
|
9853
|
-
ctx.body = { data: null, error: "Server Error" };
|
|
9854
|
-
}
|
|
9855
|
-
},
|
|
9856
|
-
async getEmailStatus(ctx) {
|
|
9857
|
-
try {
|
|
9858
|
-
const emailService = strapi2.config.get("plugin::email");
|
|
9859
|
-
ctx.status = 200;
|
|
9860
|
-
ctx.body = { data: emailService, error: null };
|
|
9861
|
-
} catch (error) {
|
|
9862
|
-
console.log("Error getting email status:", error);
|
|
9850
|
+
strapi2.log.error("Error getting config");
|
|
9863
9851
|
ctx.status = 500;
|
|
9864
9852
|
ctx.body = { data: null, error: "Server Error" };
|
|
9865
9853
|
}
|
|
@@ -9871,7 +9859,7 @@ const config$2 = ({ strapi: strapi2 }) => ({
|
|
|
9871
9859
|
ctx.status = 200;
|
|
9872
9860
|
ctx.body = { data: updatedConfig, error: null };
|
|
9873
9861
|
} catch (error) {
|
|
9874
|
-
|
|
9862
|
+
strapi2.log.error("Error updating config");
|
|
9875
9863
|
ctx.status = 500;
|
|
9876
9864
|
ctx.body = { data: null, error: "Server Error" };
|
|
9877
9865
|
}
|
|
@@ -9923,6 +9911,18 @@ const buildCookieOptionsWithExpiry = (type, absoluteExpiresAtISO, secureRequest)
|
|
|
9923
9911
|
return { ...base, expires: chosen, maxAge: Math.max(0, chosen.getTime() - now) };
|
|
9924
9912
|
};
|
|
9925
9913
|
const controller = ({ strapi: strapi2 }) => ({
|
|
9914
|
+
async verifyInfo(ctx) {
|
|
9915
|
+
const secret2 = strapi2.config.get("admin.auth.secret");
|
|
9916
|
+
const token = ctx.cookies.get("strapi_admin_mfa");
|
|
9917
|
+
try {
|
|
9918
|
+
const payload = jwt.verify(token, secret2);
|
|
9919
|
+
ctx.status = 200;
|
|
9920
|
+
ctx.body = { data: { mfaType: payload.mfaType || null }, error: null };
|
|
9921
|
+
} catch {
|
|
9922
|
+
ctx.status = 401;
|
|
9923
|
+
ctx.body = { data: null, error: "Invalid or expired MFA session" };
|
|
9924
|
+
}
|
|
9925
|
+
},
|
|
9926
9926
|
async verify(ctx) {
|
|
9927
9927
|
const sessionManager = strapi2.sessionManager;
|
|
9928
9928
|
const secret2 = strapi2.config.get("admin.auth.secret");
|
|
@@ -9947,19 +9947,20 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
9947
9947
|
).generateRefreshToken(payload.userId, payload.deviceId, {
|
|
9948
9948
|
type: payload.rememberMe ? "refresh" : "session"
|
|
9949
9949
|
});
|
|
9950
|
+
const secure = strapi2.config.get("admin.auth.cookie.secure") ?? process.env.NODE_ENV === "production";
|
|
9950
9951
|
ctx.cookies.set(
|
|
9951
9952
|
"strapi_admin_refresh",
|
|
9952
9953
|
refreshToken,
|
|
9953
9954
|
buildCookieOptionsWithExpiry(
|
|
9954
9955
|
payload.rememberMe ? "refresh" : "session",
|
|
9955
9956
|
absoluteExpiresAt,
|
|
9956
|
-
|
|
9957
|
+
secure
|
|
9957
9958
|
)
|
|
9958
9959
|
);
|
|
9959
9960
|
const accessResult = await sessionManager("admin").generateAccessToken(refreshToken);
|
|
9960
9961
|
const { token: accessToken } = accessResult;
|
|
9961
9962
|
const domain = strapi2.config.get("admin.auth.domain");
|
|
9962
|
-
const opt = { httpOnly: false, secure
|
|
9963
|
+
const opt = { httpOnly: false, secure, overwrite: true, domain };
|
|
9963
9964
|
ctx.cookies.set("jwtToken", accessToken, opt);
|
|
9964
9965
|
ctx.cookies.set("strapi_admin_mfa", null, { expires: /* @__PURE__ */ new Date(0) });
|
|
9965
9966
|
ctx.status = 200;
|
|
@@ -9968,7 +9969,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
9968
9969
|
error: null
|
|
9969
9970
|
};
|
|
9970
9971
|
} catch (error) {
|
|
9971
|
-
|
|
9972
|
+
strapi2.log.error("Error verifying MFA code");
|
|
9972
9973
|
ctx.status = 500;
|
|
9973
9974
|
ctx.body = { data: null, error: "Server Error" };
|
|
9974
9975
|
}
|
|
@@ -9991,7 +9992,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
9991
9992
|
ctx.body = { data: { message: "MFA disabled" }, error: null };
|
|
9992
9993
|
}
|
|
9993
9994
|
} catch (error) {
|
|
9994
|
-
|
|
9995
|
+
strapi2.log.error("Error enabling/disabling MFA");
|
|
9995
9996
|
ctx.status = 500;
|
|
9996
9997
|
ctx.body = { data: null, error: "Failed to update MFA" };
|
|
9997
9998
|
}
|
|
@@ -10036,7 +10037,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10036
10037
|
ctx.status = 200;
|
|
10037
10038
|
ctx.body = { data: { message: "MFA disabled" }, error: null };
|
|
10038
10039
|
} catch (error) {
|
|
10039
|
-
|
|
10040
|
+
strapi2.log.error("Error disabling MFA");
|
|
10040
10041
|
ctx.status = 500;
|
|
10041
10042
|
ctx.body = { data: null, error: "Failed to disable MFA" };
|
|
10042
10043
|
}
|
|
@@ -10064,7 +10065,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10064
10065
|
ctx.status = 200;
|
|
10065
10066
|
ctx.body = { data: { message: "Verification email sent" }, error: null };
|
|
10066
10067
|
} catch (error) {
|
|
10067
|
-
|
|
10068
|
+
strapi2.log.error("Error initiating email MFA setup");
|
|
10068
10069
|
ctx.status = 500;
|
|
10069
10070
|
ctx.body = { data: null, error: "Failed to initiate email MFA setup" };
|
|
10070
10071
|
}
|
|
@@ -10084,7 +10085,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10084
10085
|
ctx.status = 200;
|
|
10085
10086
|
ctx.body = { data: { message: "Email OTP enabled" }, error: null };
|
|
10086
10087
|
} catch (error) {
|
|
10087
|
-
|
|
10088
|
+
strapi2.log.error("Error completing email MFA setup");
|
|
10088
10089
|
ctx.status = 500;
|
|
10089
10090
|
ctx.body = { data: null, error: "Failed to enable email MFA" };
|
|
10090
10091
|
}
|
|
@@ -10105,7 +10106,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10105
10106
|
ctx.status = 200;
|
|
10106
10107
|
ctx.body = { data: { message: "Verification email sent" }, error: null };
|
|
10107
10108
|
} catch (error) {
|
|
10108
|
-
|
|
10109
|
+
strapi2.log.error("Error sending disable email OTP");
|
|
10109
10110
|
ctx.status = 500;
|
|
10110
10111
|
ctx.body = { data: null, error: "Failed to send verification email" };
|
|
10111
10112
|
}
|
|
@@ -10133,7 +10134,7 @@ const controller = ({ strapi: strapi2 }) => ({
|
|
|
10133
10134
|
ctx.status = 200;
|
|
10134
10135
|
ctx.body = { data: { message: "Verification email resent" }, error: null };
|
|
10135
10136
|
} catch (error) {
|
|
10136
|
-
|
|
10137
|
+
strapi2.log.error("Error resending login email OTP");
|
|
10137
10138
|
ctx.status = 500;
|
|
10138
10139
|
ctx.body = { data: null, error: "Failed to resend verification email" };
|
|
10139
10140
|
}
|
|
@@ -10219,35 +10220,40 @@ const config$1 = [
|
|
|
10219
10220
|
pluginName: "strapi-identity",
|
|
10220
10221
|
type: "content-api"
|
|
10221
10222
|
},
|
|
10222
|
-
config: {}
|
|
10223
|
-
},
|
|
10224
|
-
{
|
|
10225
|
-
method: "GET",
|
|
10226
|
-
path: "/config",
|
|
10227
|
-
handler: "config.getConfig",
|
|
10228
|
-
info: {
|
|
10229
|
-
apiName: "getConfig",
|
|
10230
|
-
pluginName: "strapi-identity",
|
|
10231
|
-
type: "content-api"
|
|
10232
|
-
},
|
|
10233
10223
|
config: {
|
|
10234
10224
|
policies: [
|
|
10235
|
-
"admin::isAuthenticatedAdmin"
|
|
10225
|
+
"admin::isAuthenticatedAdmin",
|
|
10226
|
+
{
|
|
10227
|
+
name: "admin::hasPermissions",
|
|
10228
|
+
config: {
|
|
10229
|
+
actions: [
|
|
10230
|
+
"plugin::strapi-identity.settings.read"
|
|
10231
|
+
]
|
|
10232
|
+
}
|
|
10233
|
+
}
|
|
10236
10234
|
]
|
|
10237
10235
|
}
|
|
10238
10236
|
},
|
|
10239
10237
|
{
|
|
10240
10238
|
method: "GET",
|
|
10241
|
-
path: "/config
|
|
10242
|
-
handler: "config.
|
|
10239
|
+
path: "/config",
|
|
10240
|
+
handler: "config.getConfig",
|
|
10243
10241
|
info: {
|
|
10244
|
-
apiName: "
|
|
10242
|
+
apiName: "getConfig",
|
|
10245
10243
|
pluginName: "strapi-identity",
|
|
10246
10244
|
type: "content-api"
|
|
10247
10245
|
},
|
|
10248
10246
|
config: {
|
|
10249
10247
|
policies: [
|
|
10250
|
-
"admin::isAuthenticatedAdmin"
|
|
10248
|
+
"admin::isAuthenticatedAdmin",
|
|
10249
|
+
{
|
|
10250
|
+
name: "admin::hasPermissions",
|
|
10251
|
+
config: {
|
|
10252
|
+
actions: [
|
|
10253
|
+
"plugin::strapi-identity.settings.read"
|
|
10254
|
+
]
|
|
10255
|
+
}
|
|
10256
|
+
}
|
|
10251
10257
|
]
|
|
10252
10258
|
}
|
|
10253
10259
|
},
|
|
@@ -10276,6 +10282,22 @@ const config$1 = [
|
|
|
10276
10282
|
}
|
|
10277
10283
|
];
|
|
10278
10284
|
const mfa = [
|
|
10285
|
+
{
|
|
10286
|
+
method: "GET",
|
|
10287
|
+
path: "/verify/info",
|
|
10288
|
+
handler: "controller.verifyInfo",
|
|
10289
|
+
info: {
|
|
10290
|
+
apiName: "verifyInfo",
|
|
10291
|
+
pluginName: "strapi-identity",
|
|
10292
|
+
type: "content-api"
|
|
10293
|
+
},
|
|
10294
|
+
config: {
|
|
10295
|
+
auth: false,
|
|
10296
|
+
policies: [
|
|
10297
|
+
"has-mfa"
|
|
10298
|
+
]
|
|
10299
|
+
}
|
|
10300
|
+
},
|
|
10279
10301
|
{
|
|
10280
10302
|
method: "POST",
|
|
10281
10303
|
path: "/verify",
|
|
@@ -10289,6 +10311,9 @@ const mfa = [
|
|
|
10289
10311
|
auth: false,
|
|
10290
10312
|
policies: [
|
|
10291
10313
|
"has-mfa"
|
|
10314
|
+
],
|
|
10315
|
+
middlewares: [
|
|
10316
|
+
"admin::rateLimit"
|
|
10292
10317
|
]
|
|
10293
10318
|
}
|
|
10294
10319
|
},
|
|
@@ -10349,7 +10374,8 @@ const mfa = [
|
|
|
10349
10374
|
auth: false,
|
|
10350
10375
|
policies: [
|
|
10351
10376
|
"has-mfa"
|
|
10352
|
-
]
|
|
10377
|
+
],
|
|
10378
|
+
middlewares: []
|
|
10353
10379
|
}
|
|
10354
10380
|
},
|
|
10355
10381
|
{
|
|
@@ -10398,7 +10424,7 @@ const isEnabled$1 = (id) => {
|
|
|
10398
10424
|
try {
|
|
10399
10425
|
return mfaToken2.count({ where: { admin_user: { id }, enabled: true } }).then((count) => count > 0);
|
|
10400
10426
|
} catch (error) {
|
|
10401
|
-
|
|
10427
|
+
strapi.log.error("Error checking if 2FA is enabled for user");
|
|
10402
10428
|
return false;
|
|
10403
10429
|
}
|
|
10404
10430
|
};
|
|
@@ -10415,7 +10441,7 @@ const reset = async (id) => {
|
|
|
10415
10441
|
existingTemp ? mfaTemp2.delete({ documentId: existingTemp.documentId }) : null
|
|
10416
10442
|
]);
|
|
10417
10443
|
} catch (error) {
|
|
10418
|
-
|
|
10444
|
+
strapi.log.error("Error resetting 2FA for user");
|
|
10419
10445
|
throw new Error("Failed to reset 2FA for user");
|
|
10420
10446
|
}
|
|
10421
10447
|
};
|
|
@@ -10479,7 +10505,7 @@ const disableEmailMFAForAllUsers = async () => {
|
|
|
10479
10505
|
)
|
|
10480
10506
|
]);
|
|
10481
10507
|
} catch (err) {
|
|
10482
|
-
|
|
10508
|
+
strapi.log.error("Error disabling email MFA for all users");
|
|
10483
10509
|
}
|
|
10484
10510
|
};
|
|
10485
10511
|
const disableMFAForAllUsers = async () => {
|
|
@@ -10495,7 +10521,7 @@ const disableMFAForAllUsers = async () => {
|
|
|
10495
10521
|
...temps.map((temp) => tempDocument.delete({ documentId: temp.documentId }))
|
|
10496
10522
|
]);
|
|
10497
10523
|
} catch (err) {
|
|
10498
|
-
|
|
10524
|
+
strapi.log.error("Error disabling MFA for all users");
|
|
10499
10525
|
}
|
|
10500
10526
|
};
|
|
10501
10527
|
const checkUserByJWT = async (jwtToken) => {
|
|
@@ -10548,7 +10574,7 @@ const send = async (to, otp) => {
|
|
|
10548
10574
|
sendConfig.replyTo = config2.response_email;
|
|
10549
10575
|
}
|
|
10550
10576
|
return emailService.send(sendConfig).catch((error) => {
|
|
10551
|
-
|
|
10577
|
+
strapi.log.error("Error sending email");
|
|
10552
10578
|
});
|
|
10553
10579
|
};
|
|
10554
10580
|
const replaceTemplateVariables = (template, variables) => {
|