mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 05:50:35 +03:00
076e3c02b2
fixes https://github.com/TryGhost/Team/issues/2160 - Adds a `batch_id` to both events that contain the same ID if they were created at the same time. - Removes duplicate signup/conversion events using the batch_id - Requires an update in mongo-knex to work (refs https://ghost.slack.com/archives/C02G9E68C/p1666773313272409?thread_ts=1666767872.375009&cid=C02G9E68C) - Some dependencies needed an update to load the latest mongo-knex - Added tiers to membersUtils, loaded on startup (we can start to use this instead of fetching it every time)
149 lines
4.4 KiB
JavaScript
149 lines
4.4 KiB
JavaScript
import ESASessionService from 'ember-simple-auth/services/session';
|
|
import RSVP from 'rsvp';
|
|
import {configureScope} from '@sentry/ember';
|
|
import {getOwner} from '@ember/application';
|
|
import {run} from '@ember/runloop';
|
|
import {inject as service} from '@ember/service';
|
|
import {task} from 'ember-concurrency';
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
export default class SessionService extends ESASessionService {
|
|
@service config;
|
|
@service('store') dataStore;
|
|
@service feature;
|
|
@service notifications;
|
|
@service router;
|
|
@service frontend;
|
|
@service settings;
|
|
@service ui;
|
|
@service upgradeStatus;
|
|
@service whatsNew;
|
|
@service membersUtils;
|
|
|
|
@tracked user = null;
|
|
|
|
skipAuthSuccessHandler = false;
|
|
|
|
async populateUser(options = {}) {
|
|
if (this.user) {
|
|
return;
|
|
}
|
|
|
|
const id = options.id || 'me';
|
|
const user = await this.dataStore.queryRecord('user', {id});
|
|
this.user = user;
|
|
}
|
|
|
|
async postAuthPreparation() {
|
|
await RSVP.all([
|
|
this.config.fetchAuthenticated(),
|
|
this.feature.fetch(),
|
|
this.settings.fetch(),
|
|
this.membersUtils.fetch()
|
|
]);
|
|
|
|
await this.frontend.loginIfNeeded();
|
|
|
|
// update Sentry with the full Ghost version which we only get after authentication
|
|
if (this.config.sentry_dsn) {
|
|
configureScope((scope) => {
|
|
scope.addEventProcessor((event) => {
|
|
return new Promise((resolve) => {
|
|
resolve({
|
|
...event,
|
|
release: `ghost@${this.config.version}`
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
this.loadServerNotifications();
|
|
this.whatsNew.fetchLatest.perform();
|
|
}
|
|
|
|
async handleAuthentication() {
|
|
if (this.handleAuthenticationTask.isRunning) {
|
|
return this.handleAuthenticationTask.last;
|
|
}
|
|
|
|
return this.handleAuthenticationTask.perform(() => {
|
|
if (this.skipAuthSuccessHandler) {
|
|
this.skipAuthSuccessHandler = false;
|
|
return;
|
|
}
|
|
|
|
super.handleAuthentication('home');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Always try to re-setup session & retry the original transition
|
|
* if user data is still available in session store although the
|
|
* ember-session is unauthenticated.
|
|
*
|
|
* If success, it will retry the original transition.
|
|
* If failed, it will be handled by the redirect to sign in.
|
|
*/
|
|
async requireAuthentication(transition, route) {
|
|
// Only when ember session invalidated
|
|
if (!this.isAuthenticated) {
|
|
transition.abort();
|
|
|
|
if (this.user) {
|
|
await this.setup();
|
|
this.notifications.clearAll();
|
|
transition.retry();
|
|
}
|
|
}
|
|
|
|
super.requireAuthentication(transition, route);
|
|
}
|
|
|
|
handleInvalidation() {
|
|
let transition = this.appLoadTransition;
|
|
|
|
if (transition) {
|
|
transition.send('authorizationFailed');
|
|
} else {
|
|
run.scheduleOnce('routerTransitions', this, 'triggerAuthorizationFailed');
|
|
}
|
|
}
|
|
|
|
// TODO: this feels hacky, find a better way than using .send
|
|
triggerAuthorizationFailed() {
|
|
getOwner(this).lookup(`route:${this.router.currentRouteName}`).send('authorizationFailed');
|
|
}
|
|
|
|
loadServerNotifications() {
|
|
if (this.isAuthenticated) {
|
|
if (!this.user.isAuthorOrContributor) {
|
|
this.dataStore.findAll('notification', {reload: true}).then((serverNotifications) => {
|
|
serverNotifications.forEach((notification) => {
|
|
if (notification.top || notification.custom) {
|
|
this.notifications.handleNotification(notification);
|
|
} else {
|
|
this.upgradeStatus.handleUpgradeNotification(notification);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
@task({drop: true})
|
|
*handleAuthenticationTask(callback) {
|
|
if (!this.user) {
|
|
try {
|
|
yield this.populateUser();
|
|
} catch (err) {
|
|
yield this.invalidate();
|
|
}
|
|
|
|
yield this.postAuthPreparation();
|
|
}
|
|
|
|
callback();
|
|
}
|
|
}
|