Skip to content

Commit

Permalink
fix: optimize query with is_locked, removed countDocuments for non-de…
Browse files Browse the repository at this point in the history
…v environments on user registration, fixed paid upgraded interpolation issue, fixed lastIndexOf for regex checks, added indices to user change pass and reset tokens, optimized home page with b64 inlining and less movement
  • Loading branch information
titanism committed Aug 10, 2023
1 parent 892cead commit b8d02a9
Show file tree
Hide file tree
Showing 27 changed files with 169 additions and 225 deletions.
2 changes: 2 additions & 0 deletions app/controllers/web/admin/emails.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ async function update(ctx) {
// set status to queued
await Emails.findByIdAndUpdate(ctx.state.email._id, {
$set: {
is_locked: false,
status: 'queued'
},
$unset: {
Expand Down Expand Up @@ -146,6 +147,7 @@ async function remove(ctx) {
);

// NOTE: we leave it up to the pre-save hook to determine the "status"
ctx.state.email.is_locked = false;
ctx.state.email.locked_by = undefined;
ctx.state.email.locked_at = undefined;
ctx.state.email = await ctx.state.email.save();
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/web/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,17 @@ async function register(ctx, next) {
throw Boom.badRequest(ctx.translateError('INVALID_PASSWORD'));

// register the user
const count = await Users.countDocuments({ group: 'admin' });
const query = {
email: body.email,
group: count === 0 ? 'admin' : 'user',
group: 'user',
locale: ctx.locale
};

if (config.env === 'development') {
const count = await Users.countDocuments({ group: 'admin' });
if (count === 0) query.group = 'admin';
}

query[config.userFields.hasVerifiedEmail] = false;
query[config.userFields.hasSetPassword] = true;
query[config.lastLocaleField] = ctx.locale;
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/web/my-account/ensure-upgraded-plan.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ function ensureUpgradedPlan(ctx, next) {

if (ctx.api)
return ctx.throw(
Boom.badRequest(ctx.translateError('PLAN_UPGRADE_REQUIRED', redirectTo))
Boom.paymentRequired(
ctx.translateError('PLAN_UPGRADE_REQUIRED', redirectTo)
)
);

if (ctx.method === 'GET' || ctx.accepts('html')) {
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/web/my-account/list-emails.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ async function listEmails(ctx) {

// domain must be on paid plan
if (domain.plan === 'free')
throw Boom.paymentRequired(ctx.translateError('PLAN_UPGRADE_REQUIRED'));
throw Boom.paymentRequired(
ctx.translateError(
'PLAN_UPGRADE_REQUIRED',
ctx.state.l(
`/my-account/domains/${ctx.state.domain.name}/billing?plan=enhanced_protection`
)
)
);

// domain cannot be in suspended domains list
if (_.isDate(domain.smtp_suspended_sent_at))
Expand Down
1 change: 1 addition & 0 deletions app/controllers/web/my-account/remove-email.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async function removeEmail(ctx, next) {
);

// NOTE: we leave it up to the pre-save hook to determine the "status"
ctx.state.email.is_locked = false;
ctx.state.email.locked_by = undefined;
ctx.state.email.locked_at = undefined;
ctx.state.email = await ctx.state.email.save();
Expand Down
27 changes: 24 additions & 3 deletions app/controllers/web/my-account/update-domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ async function updateDomain(ctx, next) {
// require paid plan
if (ctx.state.domain.plan === 'free')
return ctx.throw(
Boom.badRequest(ctx.translateError('PLAN_UPGRADE_REQUIRED'))
Boom.paymentRequired(
ctx.translateError(
'PLAN_UPGRADE_REQUIRED',
ctx.state.l(
`/my-account/domains/${ctx.state.domain.name}/billing?plan=enhanced_protection`
)
)
)
);
for (const bool of [
'has_adult_content_protection',
Expand All @@ -52,7 +59,14 @@ async function updateDomain(ctx, next) {
// require paid plan
if (ctx.state.domain.plan === 'free')
return ctx.throw(
Boom.badRequest(ctx.translateError('PLAN_UPGRADE_REQUIRED'))
Boom.paymentRequired(
ctx.translateError(
'PLAN_UPGRADE_REQUIRED',
ctx.state.l(
`/my-account/domains/${ctx.state.domain.name}/billing?plan=enhanced_protection`
)
)
)
);
ctx.state.domain.has_recipient_verification = boolean(
ctx.request.body.has_recipient_verification
Expand All @@ -70,7 +84,14 @@ async function updateDomain(ctx, next) {
!ctx.state.domain.has_custom_verification
)
return ctx.throw(
Boom.badRequest(ctx.translateError('PLAN_UPGRADE_REQUIRED'))
Boom.paymentRequired(
ctx.translateError(
'PLAN_UPGRADE_REQUIRED',
ctx.state.l(
`/my-account/domains/${ctx.state.domain.name}/billing?plan=enhanced_protection`
)
)
)
);
for (const prop of ['name', 'email', 'subject', 'redirect', 'html']) {
if (_.isString(ctx.request.body[`custom_verification_${prop}`])) {
Expand Down
2 changes: 1 addition & 1 deletion app/models/domains.js
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,7 @@ async function getTxtAddresses(
// 'foo'
// > str.slice(str.indexOf(':') + 1)
// 'https://foo.com'
const index = element.indexOf(':');
const index = element.lastIndexOf(':'); // last index because of regex usage
const addr =
index === -1
? [element]
Expand Down
6 changes: 6 additions & 0 deletions app/models/emails.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ const Emails = new mongoose.Schema({
'rejected'
]
},
// boolean used for querying
is_locked: {
type: Boolean,
default: false,
index: true
},
// `locked_by` is the IP address of which smtp server locked it for sending
locked_by: String,
// every 1m the job "unlock-emails" will unlock emails frozen for more than 5m
Expand Down
15 changes: 12 additions & 3 deletions app/models/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,20 @@ object[config.userFields.otpRecoveryKeys] = Array;

// Password reset
object[config.userFields.resetTokenExpiresAt] = Date;
object[config.userFields.resetToken] = String;
object[config.userFields.resetToken] = {
type: String,
index: true
};

// Email change
object[config.userFields.changeEmailTokenExpiresAt] = Date;
object[config.userFields.changeEmailToken] = String;
object[config.userFields.changeEmailTokenExpiresAt] = {
type: Date,
index: true
};
object[config.userFields.changeEmailToken] = {
type: String,
index: true
};
object[config.userFields.changeEmailNewAddress] = {
type: String,
trim: true,
Expand Down
41 changes: 22 additions & 19 deletions assets/css/_freddy.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,20 @@
position: relative;
background-repeat: no-repeat, repeat, no-repeat;
background-attachment: fixed;
background-position: 115% 115%, 50% 50%, 100% 100%;
background-position: 110% 110%, 50% 50%, 100% 100%;
// background-color: #333366; // purple
background-color: #191d21;
background-image: url('../img/art/planet.svg'),
url('../img/art/purple-stars.svg'), url('../img/art/glow.svg');
// TODO: at small screen size it needs to be contain !important
background-size: 40vmin, 25%, cover;
background-image: url('b64---../img/art/planet.svg---'),
url('b64---../img/art/purple-stars.svg---'), url('b64---../img/art/glow.svg---');
background-size: 40vmin, 25%, contain;
&:before {
// <https://css-tricks.com/pseudo-elements-in-the-web-animations-api/>
display: inline-block;
content: '';
background-repeat: no-repeat;
background-attachment: fixed;
background-position: -50% -50%;
background-image: url('../img/art/rocket.gif');
background-image: url('b64---../img/art/rocket.gif---');
background-size: 83.5px 65.5px;
position: fixed;
transition: all 1.5s linear;
Expand All @@ -42,36 +41,40 @@
content: '';
background-repeat: no-repeat;
background-attachment: fixed;
background-image: url('../img/art/freddy.gif');
background-image: url('b64---../img/art/freddy.gif---');
background-size: cover;
position: fixed;
transition: all 1.5s linear;
transition: all 1s ease-out;
right: 15%;
bottom: 30%;
width: 83px;
height: 97.25px;
bottom: 40%;
z-index: -1;
animation-name: floating;
animation-duration: 5s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-fill-mode: both;
width: 75.6px;
height: 106.2px;
}
@include media-breakpoint-up(sm) {
@include media-breakpoint-up(md) {
background-size: 45vmin, 25%, cover;
&:after {
width: 94.5px;
height: 132.75px;
}
}
@include media-breakpoint-up(md) {
@include media-breakpoint-up(lg) {
background-size: 50vmin, 25%, cover;
&:before {
animation-name: rocket-lg;
}
&:after {
width: 166px;
height: 194.5px;
width: 126px;
height: 177px;
}
}
@include media-breakpoint-up(lg) {
background-size: 70vmin, 25%, cover;
@include media-breakpoint-up(xl) {
background-size: 60vmin, 25%, cover;
}
}

Expand Down Expand Up @@ -101,10 +104,10 @@

@keyframes rocket-sm {
from {
background-position: -50% -50%;
background-position: -100px -100px;
}
to {
background-position: 150% 50%;
background-position: bottom right;
}
}

Expand Down
Binary file modified assets/img/art/freddy.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion assets/img/art/glow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b8d02a9

Please sign in to comment.