diff --git a/server/models/Collection.js b/server/models/Collection.js index 039420c50..5b152df2f 100644 --- a/server/models/Collection.js +++ b/server/models/Collection.js @@ -7,6 +7,7 @@ import { Op, DataTypes, sequelize } from "../sequelize"; import slugify from "../utils/slugify"; import CollectionUser from "./CollectionUser"; import Document from "./Document"; +import User from "./User"; const Collection = sequelize.define( "collection", @@ -236,6 +237,25 @@ Collection.findByPk = async function (id, options = {}) { } }; +/** + * Find the first collection that the specified user has access to. + * + * @param user User object + * @returns collection First collection in the sidebar order + */ +Collection.findFirstCollectionForUser = async (user: User) => { + const id = await user.collectionIds(); + + return Collection.findOne({ + where: { id }, + order: [ + // using LC_COLLATE:"C" because we need byte order to drive the sorting + sequelize.literal('"collection"."index" collate "C"'), + ["updatedAt", "DESC"], + ], + }); +}; + // get all the membership relationshps a user could have with the collection Collection.membershipUserIds = async (collectionId: string) => { const collection = await Collection.scope("withAllMemberships").findByPk( diff --git a/server/routes/auth/index.js b/server/routes/auth/index.js index 5974340de..3fcfb3d59 100644 --- a/server/routes/auth/index.js +++ b/server/routes/auth/index.js @@ -43,10 +43,7 @@ router.get("/redirect", auth(), async (ctx) => { const [team, collection, view] = await Promise.all([ Team.findByPk(user.teamId), - Collection.findOne({ - where: { teamId: user.teamId }, - order: [["index", "ASC"]], - }), + Collection.findFirstCollectionForUser(user), View.findOne({ where: { userId: user.id }, }), diff --git a/server/routes/auth/index.test.js b/server/routes/auth/index.test.js new file mode 100644 index 000000000..76590520e --- /dev/null +++ b/server/routes/auth/index.test.js @@ -0,0 +1,36 @@ +// @flow +import TestServer from "fetch-test-server"; +import webService from "../../services/web"; +import { buildUser, buildCollection } from "../../test/factories"; +import { flushdb } from "../../test/support"; + +const app = webService(); +const server = new TestServer(app.callback()); + +beforeEach(() => flushdb()); +afterAll(() => server.close()); + +describe("auth/redirect", () => { + it("should redirect to home", async () => { + const user = await buildUser(); + const res = await server.get( + `/auth/redirect?token=${user.getTransferToken()}`, + { redirect: "manual" } + ); + + expect(res.status).toEqual(302); + expect(res.headers.get("location").endsWith("/home")).toBeTruthy(); + }); + + it("should redirect to first collection", async () => { + const collection = await buildCollection(); + const user = await buildUser({ teamId: collection.teamId }); + const res = await server.get( + `/auth/redirect?token=${user.getTransferToken()}`, + { redirect: "manual" } + ); + + expect(res.status).toEqual(302); + expect(res.headers.get("location").endsWith(collection.url)).toBeTruthy(); + }); +}); diff --git a/server/utils/authentication.js b/server/utils/authentication.js index 66b1b85d3..230eb6896 100644 --- a/server/utils/authentication.js +++ b/server/utils/authentication.js @@ -101,10 +101,7 @@ export async function signIn( }); const [collection, view] = await Promise.all([ - Collection.findOne({ - where: { teamId: user.teamId }, - order: [["index", "ASC"]], - }), + Collection.findFirstCollectionForUser(user), View.findOne({ where: { userId: user.id }, }),