Skip to content

Commit

Permalink
fix: Prefer exact api path match in the middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
anku255 committed Jul 23, 2024
1 parent bc37fed commit 97f2f40
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 45 deletions.
1 change: 1 addition & 0 deletions lib/build/recipeModule.d.ts

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

4 changes: 2 additions & 2 deletions lib/build/recipeModule.js

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

62 changes: 41 additions & 21 deletions lib/build/supertokens.js

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

6 changes: 3 additions & 3 deletions lib/ts/recipeModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default abstract class RecipeModule {
path: NormalisedURLPath,
method: HTTPMethod,
userContext: UserContext
): Promise<{ id: string; tenantId: string } | undefined> => {
): Promise<{ id: string; tenantId: string; exactMatch: boolean } | undefined> => {
let apisHandled = this.getAPIsHandled();

const basePathStr = this.appInfo.apiBasePath.getAsStringDangerous();
Expand Down Expand Up @@ -71,7 +71,7 @@ export default abstract class RecipeModule {
tenantIdFromFrontend: DEFAULT_TENANT_ID,
userContext,
});
return { id: currAPI.id, tenantId: finalTenantId };
return { id: currAPI.id, tenantId: finalTenantId, exactMatch: true };
} else if (
remainingPath !== undefined &&
this.appInfo.apiBasePath
Expand All @@ -82,7 +82,7 @@ export default abstract class RecipeModule {
tenantIdFromFrontend: tenantId === undefined ? DEFAULT_TENANT_ID : tenantId,
userContext,
});
return { id: currAPI.id, tenantId: finalTenantId };
return { id: currAPI.id, tenantId: finalTenantId, exactMatch: false };
}
}
}
Expand Down
67 changes: 48 additions & 19 deletions lib/ts/supertokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,13 @@ export default class SuperTokens {
}

async function handleWithoutRid(recipeModules: RecipeModule[]) {
let bestMatch:
| {
recipeModule: RecipeModule;
idResult: { id: string; tenantId: string; exactMatch: boolean };
}
| undefined = undefined;

for (let i = 0; i < recipeModules.length; i++) {
logDebugMessage(
"middleware: Checking recipe ID for match: " +
Expand All @@ -373,23 +380,39 @@ export default class SuperTokens {
);
let idResult = await recipeModules[i].returnAPIIdIfCanHandleRequest(path, method, userContext);
if (idResult !== undefined) {
logDebugMessage("middleware: Request being handled by recipe. ID is: " + idResult.id);
let requestHandled = await recipeModules[i].handleAPIRequest(
idResult.id,
idResult.tenantId,
request,
response,
path,
method,
userContext
);
if (!requestHandled) {
logDebugMessage("middleware: Not handled because API returned requestHandled as false");
return false;
// The request path may or may not include the tenantId. `returnAPIIdIfCanHandleRequest` handles both cases.
// If one recipe matches with tenantId and another matches exactly, we prefer the exact match.
if (bestMatch === undefined || idResult.exactMatch) {
bestMatch = {
recipeModule: recipeModules[i],
idResult: idResult,
};
}
logDebugMessage("middleware: Ended");
return true;

if (idResult.exactMatch) {
break;
}
}
}

if (bestMatch !== undefined) {
const { idResult, recipeModule } = bestMatch;
logDebugMessage("middleware: Request being handled by recipe. ID is: " + idResult.id);
let requestHandled = await recipeModule.handleAPIRequest(
idResult.id,
idResult.tenantId,
request,
response,
path,
method,
userContext
);
if (!requestHandled) {
logDebugMessage("middleware: Not handled because API returned requestHandled as false");
return false;
}
logDebugMessage("middleware: Ended");
return true;
}
logDebugMessage("middleware: Not handling because no recipe matched");
return false;
Expand Down Expand Up @@ -434,6 +457,7 @@ export default class SuperTokens {
| {
id: string;
tenantId: string;
exactMatch: boolean;
}
| undefined = undefined;

Expand All @@ -443,13 +467,18 @@ export default class SuperTokens {
// the path and methods of the APIs exposed via those recipes is unique.
let currIdResult = await matchedRecipe[i].returnAPIIdIfCanHandleRequest(path, method, userContext);
if (currIdResult !== undefined) {
if (idResult !== undefined) {
if (
idResult === undefined ||
// The request path may or may not include the tenantId. `returnAPIIdIfCanHandleRequest` handles both cases.
// If one recipe matches with tenantId and another matches exactly, we prefer the exact match.
(currIdResult.exactMatch === true && idResult.exactMatch === false)
) {
finalMatchedRecipe = matchedRecipe[i];
idResult = currIdResult;
} else {
throw new Error(
"Two recipes have matched the same API path and method! This is a bug in the SDK. Please contact support."
);
} else {
finalMatchedRecipe = matchedRecipe[i];
idResult = currIdResult;
}
}
}
Expand Down

0 comments on commit 97f2f40

Please sign in to comment.