Skip to content

Commit

Permalink
fix: fix tenant filtering in getUsers
Browse files Browse the repository at this point in the history
  • Loading branch information
porcellus committed Oct 16, 2023
1 parent 4546e44 commit 8f7293c
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)

## [16.3.1] - 2023-10-16

### Fixes

- `getUsersNewestFirst` and `getUsersOldestFirst` will now properly filter users by tenantId.

## [16.3.0] - 2023-10-10

### Added
Expand Down
11 changes: 7 additions & 4 deletions lib/build/framework/fastify/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
// @ts-nocheck
/// <reference types="node" />
export type { SessionRequest } from "./framework";
export declare const plugin: import("fastify").FastifyPluginCallback<Record<never, never>, import("http").Server>;
export declare const plugin: import("fastify").FastifyPluginCallback<
Record<never, never>,
import("fastify").RawServerDefault
>;
export declare const errorHandler: () => (
err: any,
req: import("fastify").FastifyRequest<
import("fastify/types/route").RouteGenericInterface,
import("http").Server,
import("fastify").RawServerDefault,
import("http").IncomingMessage
>,
res: import("fastify").FastifyReply<
import("http").Server,
import("fastify").RawServerDefault,
import("http").IncomingMessage,
import("http").ServerResponse,
import("http").ServerResponse<import("http").IncomingMessage>,
import("fastify/types/route").RouteGenericInterface,
unknown
>
Expand Down
2 changes: 1 addition & 1 deletion lib/build/framework/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export declare function setCookieForServerResponse(
expires: number,
path: string,
sameSite: "strict" | "lax" | "none"
): ServerResponse;
): ServerResponse<IncomingMessage>;
export declare function getCookieValueToSetInHeader(
prev: string | string[] | undefined,
val: string | string[],
Expand Down
6 changes: 4 additions & 2 deletions lib/build/recipe/accountlinking/recipeImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ const normalisedURLPath_1 = __importDefault(require("../../normalisedURLPath"));
const user_1 = require("../../user");
function getRecipeImplementation(querier, config, recipeInstance) {
return {
getUsers: async function ({ timeJoinedOrder, limit, paginationToken, includeRecipeIds, query }) {
getUsers: async function ({ tenantId, timeJoinedOrder, limit, paginationToken, includeRecipeIds, query }) {
let includeRecipeIdsStr = undefined;
if (includeRecipeIds !== undefined) {
includeRecipeIdsStr = includeRecipeIds.join(",");
}
let response = await querier.sendGetRequest(
new normalisedURLPath_1.default("/users"),
new normalisedURLPath_1.default(
`${tenantId !== null && tenantId !== void 0 ? tenantId : "public"}/users`
),
Object.assign(
{
includeRecipeIds: includeRecipeIdsStr,
Expand Down
1 change: 1 addition & 0 deletions lib/build/recipe/accountlinking/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export declare type TypeNormalisedInput = {
};
export declare type RecipeInterface = {
getUsers: (input: {
tenantId: string;
timeJoinedOrder: "ASC" | "DESC";
limit?: number;
paginationToken?: string;
Expand Down
2 changes: 1 addition & 1 deletion lib/build/version.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/build/version.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion lib/ts/recipe/accountlinking/recipeImplementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ export default function getRecipeImplementation(
getUsers: async function (
this: RecipeInterface,
{
tenantId,
timeJoinedOrder,
limit,
paginationToken,
includeRecipeIds,
query,
}: {
tenantId: string;
timeJoinedOrder: "ASC" | "DESC";
limit?: number;
paginationToken?: string;
Expand All @@ -50,7 +52,7 @@ export default function getRecipeImplementation(
if (includeRecipeIds !== undefined) {
includeRecipeIdsStr = includeRecipeIds.join(",");
}
let response = await querier.sendGetRequest(new NormalisedURLPath("/users"), {
let response = await querier.sendGetRequest(new NormalisedURLPath(`${tenantId ?? "public"}/users`), {
includeRecipeIds: includeRecipeIdsStr,
timeJoinedOrder: timeJoinedOrder,
limit: limit,
Expand Down
1 change: 1 addition & 0 deletions lib/ts/recipe/accountlinking/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export type TypeNormalisedInput = {

export type RecipeInterface = {
getUsers: (input: {
tenantId: string;
timeJoinedOrder: "ASC" | "DESC";
limit?: number;
paginationToken?: string;
Expand Down
2 changes: 1 addition & 1 deletion lib/ts/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
export const version = "16.3.0";
export const version = "16.3.1";

export const cdiSupported = ["4.0"];

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "supertokens-node",
"version": "16.3.0",
"version": "16.3.1",
"description": "NodeJS driver for SuperTokens core",
"main": "index.js",
"scripts": {
Expand Down
126 changes: 126 additions & 0 deletions test/accountlinking/helperFunctions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ let { ProcessState, PROCESS_STATE } = require("../../lib/build/processState");
let EmailPassword = require("../../recipe/emailpassword");
let EmailVerification = require("../../recipe/emailverification");
let ThirdParty = require("../../recipe/thirdparty");
let Multitenancy = require("../../recipe/multitenancy");
let AccountLinking = require("../../recipe/accountlinking");
let AccountLinkingRecipe = require("../../lib/build/recipe/accountlinking/recipe").default;

Expand Down Expand Up @@ -1137,6 +1138,70 @@ describe(`accountlinkingTests: ${printPath("[test/accountlinking/helperFunctions
});

describe("listUsersByAccountInfo tests", function () {
it("listUsersByAccountInfo filters by tenantId", async function () {
const connectionURI = await startSTWithMultitenancyAndAccountLinking();

supertokens.init({
supertokens: {
connectionURI,
},
appInfo: {
apiDomain: "api.supertokens.io",
appName: "SuperTokens",
websiteDomain: "supertokens.io",
},
recipeList: [
Multitenancy.init(),
EmailPassword.init(),
ThirdParty.init({
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "google",
clients: [
{
clientId: "",
clientSecret: "",
},
],
},
},
],
},
}),
Session.init(),
],
});
await Multitenancy.createOrUpdateTenant("tenant1", {
thirdPartyEnabled: true,
emailPasswordEnabled: true,
});

const { user: pubUser } = await EmailPassword.signUp("public", "test@example.com", "password123");

const { user: t1User } = await ThirdParty.manuallyCreateOrUpdateUser(
"tenant1",
"google",
"abc",
"test@example.com",
false
);

let t1UserList = await supertokens.listUsersByAccountInfo("tenant1", {
email: "test@example.com",
});

assert.strictEqual(t1UserList.length, 1);
assert.strictEqual(t1UserList[0].id, t1User.id);

let pubUserList = await supertokens.listUsersByAccountInfo("public", {
email: "test@example.com",
});
assert.strictEqual(pubUserList.length, 1);
assert.strictEqual(pubUserList[0].id, pubUser.id);
});

it("listUsersByAccountInfo does and properly", async function () {
const connectionURI = await startSTWithMultitenancyAndAccountLinking();

Expand Down Expand Up @@ -1242,6 +1307,67 @@ describe(`accountlinkingTests: ${printPath("[test/accountlinking/helperFunctions
});
});

describe("getUsers tests", function () {
it("getUsers filters by tenantId", async function () {
const connectionURI = await startSTWithMultitenancyAndAccountLinking();

supertokens.init({
supertokens: {
connectionURI,
},
appInfo: {
apiDomain: "api.supertokens.io",
appName: "SuperTokens",
websiteDomain: "supertokens.io",
},
recipeList: [
Multitenancy.init(),
EmailPassword.init(),
ThirdParty.init({
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "google",
clients: [
{
clientId: "",
clientSecret: "",
},
],
},
},
],
},
}),
Session.init(),
],
});
await Multitenancy.createOrUpdateTenant("tenant1", {
thirdPartyEnabled: true,
emailPasswordEnabled: true,
});

const { user: pubUser } = await EmailPassword.signUp("public", "test@example.com", "password123");

const { user: t1User } = await ThirdParty.manuallyCreateOrUpdateUser(
"tenant1",
"google",
"abc",
"test@example.com",
false
);

let { users: t1UserList } = await supertokens.getUsersNewestFirst({ tenantId: "tenant1" });
assert.strictEqual(t1UserList.length, 1);
assert.strictEqual(t1UserList[0].id, t1User.id);

let { users: pubUserList } = await supertokens.getUsersNewestFirst({ tenantId: "public" });
assert.strictEqual(pubUserList.length, 1);
assert.strictEqual(pubUserList[0].id, pubUser.id);
});
});

describe("isEmailChangeAllowed tests", function () {
it("isEmailChangeAllowed returns false if checking for email which belongs to other primary and if email password user is not a primary user or is not linked, and account linking is enabled and email verification is required", async function () {
const connectionURI = await startSTWithMultitenancyAndAccountLinking();
Expand Down

0 comments on commit 8f7293c

Please sign in to comment.