chore: Refactor authentication pass between subdomains (#1619)
* fix: Use get request instead of cookie to transfer token between domains * Add domain to database Add redirects to team domain when present * 30s -> 1m * fix: Avoid redirect loop if subdomain and domain set * fix: Create a transfer specific token to prevent replay requests * refactor: Move isCustomDomain out of shared as it won't work on the client
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
// @flow
|
||||
import crypto from "crypto";
|
||||
import addMinutes from "date-fns/add_minutes";
|
||||
import subMinutes from "date-fns/sub_minutes";
|
||||
import JWT from "jsonwebtoken";
|
||||
import uuid from "uuid";
|
||||
@ -91,12 +92,12 @@ User.prototype.collectionIds = async function (options = {}) {
|
||||
.map((c) => c.id);
|
||||
};
|
||||
|
||||
User.prototype.updateActiveAt = function (ip) {
|
||||
User.prototype.updateActiveAt = function (ip, force = false) {
|
||||
const fiveMinutesAgo = subMinutes(new Date(), 5);
|
||||
|
||||
// ensure this is updated only every few minutes otherwise
|
||||
// we'll be constantly writing to the DB as API requests happen
|
||||
if (this.lastActiveAt < fiveMinutesAgo) {
|
||||
if (this.lastActiveAt < fiveMinutesAgo || force) {
|
||||
this.lastActiveAt = new Date();
|
||||
this.lastActiveIp = ip;
|
||||
return this.save({ hooks: false });
|
||||
@ -109,17 +110,42 @@ User.prototype.updateSignedIn = function (ip) {
|
||||
return this.save({ hooks: false });
|
||||
};
|
||||
|
||||
User.prototype.getJwtToken = function () {
|
||||
return JWT.sign({ id: this.id }, this.jwtSecret);
|
||||
// Returns a session token that is used to make API requests and is stored
|
||||
// in the client browser cookies to remain logged in.
|
||||
User.prototype.getJwtToken = function (expiresAt?: Date) {
|
||||
return JWT.sign(
|
||||
{
|
||||
id: this.id,
|
||||
expiresAt: expiresAt ? expiresAt.toISOString() : undefined,
|
||||
type: "session",
|
||||
},
|
||||
this.jwtSecret
|
||||
);
|
||||
};
|
||||
|
||||
// Returns a temporary token that is only used for transferring a session
|
||||
// between subdomains or domains. It has a short expiry and can only be used once
|
||||
User.prototype.getTransferToken = function () {
|
||||
return JWT.sign(
|
||||
{
|
||||
id: this.id,
|
||||
createdAt: new Date().toISOString(),
|
||||
expiresAt: addMinutes(new Date(), 1).toISOString(),
|
||||
type: "transfer",
|
||||
},
|
||||
this.jwtSecret
|
||||
);
|
||||
};
|
||||
|
||||
// Returns a temporary token that is only used for logging in from an email
|
||||
// It can only be used to sign in once and has a medium length expiry
|
||||
User.prototype.getEmailSigninToken = function () {
|
||||
if (this.service && this.service !== "email") {
|
||||
throw new Error("Cannot generate email signin token for OAuth user");
|
||||
}
|
||||
|
||||
return JWT.sign(
|
||||
{ id: this.id, createdAt: new Date().toISOString() },
|
||||
{ id: this.id, createdAt: new Date().toISOString(), type: "email-signin" },
|
||||
this.jwtSecret
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user