FIX: CurrentUser now must be passed to resolveTimezone and user card local time issues (#9734)

* This is to prevent user's timezones being changed accidentally
e.g. by admin looking at a user
* This problem only occurred via the user card, however the user card
was still calling userTimezone even if the setting to display user
time in card was disabled
This commit is contained in:
Martin Brennan 2020-05-11 11:01:47 +10:00 committed by GitHub
parent 44712c5f98
commit 12d4d51d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 78 additions and 21 deletions

View File

@ -72,7 +72,10 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
@discourseComputed("user")
userTimezone(user) {
return user.resolvedTimezone();
if (!this.showUserLocalTime) {
return;
}
return user.resolvedTimezone(this.currentUser);
},
@discourseComputed("userTimezone")

View File

@ -73,7 +73,7 @@ export default Controller.extend(ModalFunctionality, {
customReminderTime: this._defaultCustomReminderTime(),
lastCustomReminderDate: null,
lastCustomReminderTime: null,
userTimezone: this.currentUser.resolvedTimezone(),
userTimezone: this.currentUser.resolvedTimezone(this.currentUser),
showOptions: false,
options: {},
model: this.model || {}

View File

@ -109,7 +109,7 @@ export default {
return I18n.t("bookmarked.help.unbookmark_with_reminder", {
reminder_at: formattedReminderTime(
bookmark_reminder_at,
currentUser.resolvedTimezone()
currentUser.resolvedTimezone(currentUser)
)
});
}

View File

@ -113,7 +113,7 @@ const Bookmark = RestModel.extend({
formattedReminder(bookmarkReminderAt, currentUser) {
return formattedReminderTime(
bookmarkReminderAt,
currentUser.resolvedTimezone()
currentUser.resolvedTimezone(currentUser)
).capitalize();
},

View File

@ -849,17 +849,21 @@ const User = RestModel.extend({
);
},
resolvedTimezone() {
if (this._timezone) {
resolvedTimezone(currentUser) {
if (this.hasSavedTimezone()) {
return this._timezone;
}
this.changeTimezone(moment.tz.guess());
ajax(userPath(this.username + ".json"), {
type: "PUT",
dataType: "json",
data: { timezone: this._timezone }
});
// only change the timezone and save it if we are
// looking at our own user
if (currentUser.id === this.id) {
this.changeTimezone(moment.tz.guess());
ajax(userPath(this.username + ".json"), {
type: "PUT",
dataType: "json",
data: { timezone: this._timezone }
});
}
return this._timezone;
},
@ -868,6 +872,13 @@ const User = RestModel.extend({
this._timezone = tz;
},
hasSavedTimezone() {
if (this._timezone) {
return true;
}
return false;
},
calculateMutedIds(notificationLevel, id, type) {
const muted_ids = this.get(type);
if (notificationLevel === NotificationLevels.MUTED) {

View File

@ -302,7 +302,7 @@ registerButton("bookmark", attrs => {
if (attrs.bookmarkReminderAt) {
let formattedReminder = formattedReminderTime(
attrs.bookmarkReminderAt,
Discourse.currentUser.resolvedTimezone()
Discourse.currentUser.resolvedTimezone(Discourse.currentUser)
);
title = "bookmarks.created_with_reminder";
titleOptions.date = formattedReminder;

View File

@ -205,7 +205,7 @@ test("Editing a bookmark", async assert => {
mockSuccessfulBookmarkPost(assert);
await visit("/t/internationalization-localization/280");
let now = moment.tz(loggedInUser().resolvedTimezone());
let now = moment.tz(loggedInUser().resolvedTimezone(loggedInUser()));
let tomorrow = now.add(1, "day").format("YYYY-MM-DD");
await openBookmarkModal();
await fillIn("input#bookmark-name", "Test name");
@ -234,7 +234,7 @@ test("Editing a bookmark that has a Later Today reminder, and it is before 6pm t
mockSuccessfulBookmarkPost(assert);
let clock = fakeTime(
"2020-05-04T13:00:00",
loggedInUser().resolvedTimezone()
loggedInUser().resolvedTimezone(loggedInUser())
);
await timeStep(clock, () =>
visit("/t/internationalization-localization/280")

View File

@ -64,6 +64,29 @@ QUnit.test("user card local time", async assert => {
);
});
QUnit.test(
"user card local time - does not update timezone for another user",
async assert => {
User.current().changeTimezone("Australia/Brisbane");
let cardResponse = _.clone(userFixtures["/u/charlie/card.json"]);
delete cardResponse.user.timezone;
pretender.get("/u/charlie/card.json", () => [
200,
{ "Content-Type": "application/json" },
cardResponse
]);
await visit("/t/internationalization-localization/280");
await click("a[data-user-card=charlie]:first");
assert.not(
exists(".user-card .local-time"),
"it does not show the local time if the user card returns a null/undefined timezone for another user"
);
}
);
acceptance("User Card", { loggedIn: true });
QUnit.test("user card", async assert => {

View File

@ -114,7 +114,9 @@ QUnit.test(
function(assert) {
let dt = moment.tz(
"2019-12-11T11:37:16",
BookmarkController.currentUser.resolvedTimezone()
BookmarkController.currentUser.resolvedTimezone(
BookmarkController.currentUser
)
);
assert.equal(
@ -208,7 +210,9 @@ QUnit.test(
moment
.tz(
"2028-12-12 08:00",
BookmarkController.currentUser.resolvedTimezone()
BookmarkController.currentUser.resolvedTimezone(
BookmarkController.currentUser
)
)
.toString(),
"the custom date and time are parsed correctly with default time"

View File

@ -71,7 +71,7 @@ QUnit.test("canMangeGroup", assert => {
QUnit.test("resolvedTimezone", assert => {
const tz = "Australia/Brisbane";
let user = User.create({ timezone: tz, username: "chuck" });
let user = User.create({ timezone: tz, username: "chuck", id: 111 });
let stub = sandbox.stub(moment.tz, "guess").returns("America/Chicago");
pretender.put("/u/chuck.json", () => {
@ -80,7 +80,7 @@ QUnit.test("resolvedTimezone", assert => {
let spy = sandbox.spy(ajaxlib, "ajax");
assert.equal(
user.resolvedTimezone(),
user.resolvedTimezone(user),
tz,
"if the user already has a timezone return it"
);
@ -88,9 +88,9 @@ QUnit.test("resolvedTimezone", assert => {
spy.notCalled,
"if the user already has a timezone do not call AJAX update"
);
user = User.create({ username: "chuck" });
user = User.create({ username: "chuck", id: 111 });
assert.equal(
user.resolvedTimezone(),
user.resolvedTimezone(user),
"America/Chicago",
"if the user has no timezone guess it with moment"
);
@ -102,6 +102,22 @@ QUnit.test("resolvedTimezone", assert => {
}),
"if the user has no timezone save it with an AJAX update"
);
let otherUser = User.create({ username: "howardhamlin", id: 999 });
assert.equal(
otherUser.resolvedTimezone(user),
null,
"if the user has no timezone and the user is not the current user, do NOT guess with moment"
);
assert.not(
spy.calledWith("/u/howardhamlin.json", {
type: "PUT",
dataType: "json",
data: { timezone: "America/Chicago" }
}),
"if the user has no timezone, and the user is not the current user, do NOT save it with an AJAX update"
);
stub.restore();
});