Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Emailpassword accountlinking #501

Merged
merged 95 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
7772020
recipe interface changes for account linking
bhumilsarvaiya Dec 23, 2022
3db3a01
account linking implementation
bhumilsarvaiya Dec 25, 2022
65f34af
user context update
bhumilsarvaiya Dec 25, 2022
627aa52
Merge branch 'account-linking-interface-update' into account-linking-…
bhumilsarvaiya Dec 25, 2022
90e2f28
code udpate
bhumilsarvaiya Dec 25, 2022
5531c24
types update
bhumilsarvaiya Dec 26, 2022
5ff083b
Merge branch 'account-linking-interface-update' into account-linking-…
bhumilsarvaiya Dec 26, 2022
df027fe
Update lib/ts/recipe/accountlinking/types.ts
bhumilsarvaiya Dec 29, 2022
61d6050
Update lib/ts/recipe/accountlinking/types.ts
bhumilsarvaiya Dec 29, 2022
da4a11b
Update lib/ts/recipe/accountlinking/types.ts
bhumilsarvaiya Dec 29, 2022
e8fb6df
return type update
bhumilsarvaiya Dec 29, 2022
dce3429
index file updated
bhumilsarvaiya Dec 29, 2022
00458f7
Merge branch 'account-linking-interface-update' into account-linking-…
bhumilsarvaiya Dec 29, 2022
8f08c86
merge with account-linking interface
bhumilsarvaiya Dec 29, 2022
2336e72
resolves conflicts
rishabhpoddar Dec 30, 2022
7e4d64f
Update lib/ts/recipe/accountlinking/recipeImplementation.ts
bhumilsarvaiya Dec 31, 2022
e1af592
code review changes
bhumilsarvaiya Jan 3, 2023
91f51a5
Update lib/ts/recipe/accountlinking/recipeImplementation.ts
bhumilsarvaiya Jan 4, 2023
983a16b
Update lib/ts/recipe/accountlinking/recipe.ts
bhumilsarvaiya Jan 4, 2023
ce31b94
Update lib/ts/recipe/accountlinking/recipe.ts
bhumilsarvaiya Jan 4, 2023
680ff1f
code review changes
bhumilsarvaiya Jan 16, 2023
e6326c4
Merge branch 'account-linking-implementation' of github.com:supertoke…
bhumilsarvaiya Jan 16, 2023
c56aae3
code review changes
bhumilsarvaiya Jan 16, 2023
bb44a89
code review changes
bhumilsarvaiya Jan 16, 2023
9c0c766
code review changes
bhumilsarvaiya Jan 18, 2023
c4302d0
review changes
bhumilsarvaiya Jan 22, 2023
8613c6c
sign-up post login updated
bhumilsarvaiya Jan 29, 2023
da1c640
sign-up post login updated
bhumilsarvaiya Jan 29, 2023
9cddbba
sign-up API implementation update
bhumilsarvaiya Jan 30, 2023
ed04227
import update
bhumilsarvaiya Jan 30, 2023
fb5fb43
function import update
bhumilsarvaiya Feb 1, 2023
c0fd1be
changes in signup recipeimplementation
bhumilsarvaiya Feb 2, 2023
9c6d33a
recipeImplementation types update
bhumilsarvaiya Feb 8, 2023
69bd690
merge with 13.0
bhumilsarvaiya Feb 11, 2023
6c05fa0
merge with account-linking implementation
bhumilsarvaiya Feb 11, 2023
8f224d9
merge with account-linking implementation
bhumilsarvaiya Feb 11, 2023
e1816f7
merge with latest 13.0
bhumilsarvaiya Feb 12, 2023
1765311
merge with 13.0
bhumilsarvaiya Feb 12, 2023
e371112
recipe implementation update
bhumilsarvaiya Feb 12, 2023
30816fe
account linking claim
bhumilsarvaiya Feb 13, 2023
53de40e
session claim update
bhumilsarvaiya Feb 13, 2023
8fe7538
merge with account-linking
bhumilsarvaiya Feb 13, 2023
4b0ad7d
changes to dashboard recipe types
rishabhpoddar Feb 22, 2023
ed5865c
removes unnecessary functions exposed from account linking recipe
rishabhpoddar Feb 22, 2023
de434e9
adds a precautionary check
rishabhpoddar Feb 23, 2023
6603119
small change
rishabhpoddar Feb 23, 2023
8bd6689
Update lib/ts/types.ts
bhumilsarvaiya Feb 24, 2023
35f0016
Update lib/ts/index.ts
bhumilsarvaiya Feb 24, 2023
30802c0
Update lib/ts/supertokens.ts
bhumilsarvaiya Feb 24, 2023
943dde4
Update lib/ts/recipe/dashboard/api/usersGet.ts
bhumilsarvaiya Feb 24, 2023
84d56d7
Update lib/ts/index.ts
bhumilsarvaiya Feb 24, 2023
5b68aa2
Update lib/ts/index.ts
bhumilsarvaiya Feb 24, 2023
e36e9ff
Update lib/ts/index.ts
bhumilsarvaiya Feb 24, 2023
1db095f
Update lib/ts/recipe/accountlinking/types.ts
bhumilsarvaiya Feb 24, 2023
2454f46
Update lib/ts/recipe/accountlinking/recipe.ts
bhumilsarvaiya Feb 24, 2023
8b021e6
Update lib/ts/recipe/accountlinking/recipe.ts
bhumilsarvaiya Feb 24, 2023
6a0134b
Update lib/ts/recipe/accountlinking/recipe.ts
bhumilsarvaiya Feb 24, 2023
10f3d9f
Update lib/ts/recipe/accountlinking/types.ts
bhumilsarvaiya Feb 24, 2023
ec3eca3
Update lib/ts/recipe/accountlinking/recipe.ts
bhumilsarvaiya Feb 24, 2023
30e0f30
code review changes
bhumilsarvaiya Feb 24, 2023
55525dc
mark email as verify if it is already verified in either primary user…
bhumilsarvaiya Feb 24, 2023
4bc7809
fixes and refactors
rishabhpoddar Feb 27, 2023
9fb3586
account linking: fixes bugs and refactors (#498)
rishabhpoddar Mar 1, 2023
2f16711
removes redundant check
rishabhpoddar Mar 1, 2023
2c29bf4
account linking: removes ANOTHER from canCreatePrimaryUserId status r…
rishabhpoddar Mar 1, 2023
d5ffa6f
change to canLinkAccounts
rishabhpoddar Mar 1, 2023
e05b481
Update lib/ts/recipe/accountlinking/recipeImplementation.ts
bhumilsarvaiya Mar 2, 2023
4034ea1
Update lib/ts/recipe/accountlinking/types.ts
bhumilsarvaiya Mar 2, 2023
6e3d61b
Update lib/ts/recipe/accountlinking/recipeImplementation.ts
bhumilsarvaiya Mar 2, 2023
5fd30cf
code review changes
bhumilsarvaiya Mar 2, 2023
2ca0d87
merge with accounlinking implementation branch
bhumilsarvaiya Mar 2, 2023
0c1ac24
merged in account-linking
bhumilsarvaiya Mar 4, 2023
25613e4
review changes
bhumilsarvaiya Mar 12, 2023
5059468
createdNewUser changes
bhumilsarvaiya Mar 12, 2023
1fc5d58
adds comments
rishabhpoddar Mar 14, 2023
c201083
fixes
rishabhpoddar Mar 30, 2023
2a0fcb2
review changes (#511)
rishabhpoddar Mar 30, 2023
83e6377
merges - ts fail
rishabhpoddar May 2, 2023
6866314
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
abebdb4
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
cc9ea9a
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
e3f8f63
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
d354bfb
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
883eabf
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
226215d
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
225ae46
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
98c6532
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
21ec963
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
686fb30
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
9c704de
more fixes - ts still not compiling
rishabhpoddar May 2, 2023
5212cc4
more fixes - ts still not compiling
rishabhpoddar May 7, 2023
27eddc3
more fixes - ts still not compiling
rishabhpoddar May 7, 2023
adb8732
more fixes - ts still not compiling
rishabhpoddar May 7, 2023
31ed54a
more fixes - ts still not compiling
rishabhpoddar May 7, 2023
2f943f4
fixes all ts issues
rishabhpoddar May 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Type of `User` object returned by get users function
- Functions `deleteuser`, `getUsersNewestFirst` and `getUsersOldestFirst` are now based on account linking recipe
- Function `deleteuser` takes a new parameter `removeAllLinkedAccounts` which will be `true` by default
- Generate Password Reset Token API logic updated

### Removed:

- For EmailPassword recipe input, resetPasswordUsingTokenFeature user input removed

## [13.0.2] - 2023-02-10

Expand Down
9 changes: 9 additions & 0 deletions lib/build/recipe/accountlinking/accountLinkingClaim.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @ts-nocheck
import { PrimitiveClaim } from "../session/claims";
/**
* We include "Class" in the class name, because it makes it easier to import the right thing (the instance) instead of this.
* */
export declare class AccountLinkingClaimClass extends PrimitiveClaim<string> {
constructor();
}
export declare const AccountLinkingClaim: AccountLinkingClaimClass;
19 changes: 19 additions & 0 deletions lib/build/recipe/accountlinking/accountLinkingClaim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccountLinkingClaim = exports.AccountLinkingClaimClass = void 0;
const claims_1 = require("../session/claims");
/**
* We include "Class" in the class name, because it makes it easier to import the right thing (the instance) instead of this.
* */
class AccountLinkingClaimClass extends claims_1.PrimitiveClaim {
constructor() {
super({
key: "st-linking",
fetchValue(_, __, ___) {
return undefined;
},
});
}
}
exports.AccountLinkingClaimClass = AccountLinkingClaimClass;
exports.AccountLinkingClaim = new AccountLinkingClaimClass();
4 changes: 2 additions & 2 deletions lib/build/recipe/accountlinking/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class Wrapper {
): Promise<
| {
status: "OK";
user: import("../../types").User;
user: import("../emailpassword").User;
wasAlreadyAPrimaryUser: boolean;
}
| {
Expand Down Expand Up @@ -104,7 +104,7 @@ export default class Wrapper {
static fetchFromAccountToLinkTable(
recipeUserId: string,
userContext?: any
): Promise<import("../../types").User | undefined>;
): Promise<import("../emailpassword").User | undefined>;
static storeIntoAccountToLinkTable(
recipeUserId: string,
primaryUserId: string,
Expand Down
26 changes: 23 additions & 3 deletions lib/build/recipe/accountlinking/recipe.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,43 @@ export default class Recipe extends RecipeModule {
newUser: AccountInfoWithRecipeId;
userContext: any;
}) => Promise<boolean>;
linkAccountsWithUserFromSession: ({
linkAccountsWithUserFromSession: <T>({
session,
newUser,
createRecipeUserFunc,
verifyCredentialsFunc,
userContext,
}: {
session: SessionContainer;
newUser: AccountInfoWithRecipeId;
createRecipeUserFunc: (newUser: AccountInfoWithRecipeId) => Promise<void>;
createRecipeUserFunc: () => Promise<void>;
verifyCredentialsFunc: () => Promise<
| {
status: "OK";
}
| {
status: "CUSTOM_RESPONSE";
resp: T;
}
>;
userContext: any;
}) => Promise<
| {
status: "OK" | "NEW_ACCOUNT_NEEDS_TO_BE_VERIFIED_ERROR";
status: "OK";
wereAccountsAlreadyLinked: boolean;
}
| {
status: "ACCOUNT_LINKING_NOT_ALLOWED_ERROR";
description: string;
}
| {
status: "NEW_ACCOUNT_NEEDS_TO_BE_VERIFIED_ERROR";
primaryUserId: string;
recipeUserId: string;
}
| {
status: "CUSTOM_RESPONSE";
resp: T;
}
>;
}
63 changes: 49 additions & 14 deletions lib/build/recipe/accountlinking/recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,13 @@ class Recipe extends recipeModule_1.default {
}
return false;
});
this.linkAccountsWithUserFromSession = ({ session, newUser, createRecipeUserFunc, userContext }) =>
this.linkAccountsWithUserFromSession = ({
session,
newUser,
createRecipeUserFunc,
verifyCredentialsFunc,
userContext,
}) =>
__awaiter(this, void 0, void 0, function* () {
// In order to link the newUser to the session user,
// we need to first make sure that the session user
Expand Down Expand Up @@ -384,6 +390,7 @@ class Recipe extends recipeModule_1.default {
session,
newUser,
createRecipeUserFunc,
verifyCredentialsFunc,
userContext,
});
} else if (
Expand Down Expand Up @@ -426,30 +433,24 @@ class Recipe extends recipeModule_1.default {
accountInfo: newUser,
userContext,
});
let newUserIsVerified = false;
const userObjThatHasSameAccountInfoAndRecipeIdAsNewUser = usersArrayThatHaveSameAccountInfoAsNewUser.find(
(u) =>
u.loginMethods.find((lU) => {
let found = false;
if (lU.recipeId !== newUser.recipeId) {
return false;
}
if (newUser.recipeId === "thirdparty") {
if (lU.thirdParty === undefined) {
return false;
}
found =
return (
lU.thirdParty.id === newUser.thirdParty.id &&
lU.thirdParty.userId === newUser.thirdParty.userId;
lU.thirdParty.userId === newUser.thirdParty.userId
);
} else {
found = lU.email === newUser.email || newUser.phoneNumber === newUser.phoneNumber;
}
if (!found) {
return false;
return lU.email === newUser.email || newUser.phoneNumber === newUser.phoneNumber;
}
newUserIsVerified = lU.verified;
return true;
})
}) !== undefined
);
if (userObjThatHasSameAccountInfoAndRecipeIdAsNewUser === undefined) {
/*
Expand All @@ -468,25 +469,58 @@ class Recipe extends recipeModule_1.default {
};
}
// we create the new recipe user
yield createRecipeUserFunc(newUser);
yield createRecipeUserFunc();
// now when we recurse, the new recipe user will be found and we can try linking again.
return yield this.linkAccountsWithUserFromSession({
session,
newUser,
createRecipeUserFunc,
verifyCredentialsFunc,
userContext,
});
} else {
// since the user already exists, we should first verify the credentials
// before continuing to link the accounts.
let verifyResult = yield verifyCredentialsFunc();
if (verifyResult.status === "CUSTOM_RESPONSE") {
return verifyResult;
}
// this means that the verification was fine and we can continue..
}
// we check if the userObjThatHasSameAccountInfoAndRecipeIdAsNewUser is
// a primary user or not, and if it is, then it means that our newUser
// is already linked so we can return early.
if (userObjThatHasSameAccountInfoAndRecipeIdAsNewUser.isPrimaryUser) {
if (userObjThatHasSameAccountInfoAndRecipeIdAsNewUser.id === existingUser.id) {
// this means that the accounts we want to link are already linked.
return {
status: "OK",
wereAccountsAlreadyLinked: true,
};
} else {
return {
status: "ACCOUNT_LINKING_NOT_ALLOWED_ERROR",
description: "New user is already linked to another account",
};
}
}
// now we check about the email verification of the new user. If it's verified, we proceed
// to try and link the accounts, and if not, we send email verification error ONLY if the email
// or phone number of the new account is different compared to the existing account.
if (usersArrayThatHaveSameAccountInfoAsNewUser.find((u) => u.id === existingUser.id) === undefined) {
// this means that the existing user does not share anything in common with the new user
// in terms of account info. So we check for email verification status..
if (!newUserIsVerified && shouldDoAccountLinking.shouldRequireVerification) {
if (
!userObjThatHasSameAccountInfoAndRecipeIdAsNewUser.loginMethods[0].verified &&
shouldDoAccountLinking.shouldRequireVerification
) {
// we stop the flow and ask the user to verify this email first.
// the recipe ID is the userObjThatHasSameAccountInfoAndRecipeIdAsNewUser.id
// cause above we checked that userObjThatHasSameAccountInfoAndRecipeIdAsNewUser.isPrimaryUser is false.
return {
status: "NEW_ACCOUNT_NEEDS_TO_BE_VERIFIED_ERROR",
primaryUserId: existingUser.id,
recipeUserId: userObjThatHasSameAccountInfoAndRecipeIdAsNewUser.id,
};
}
}
Expand All @@ -498,6 +532,7 @@ class Recipe extends recipeModule_1.default {
if (linkAccountResponse.status === "OK") {
return {
status: "OK",
wereAccountsAlreadyLinked: linkAccountResponse.accountsAlreadyLinked,
};
} else if (
linkAccountResponse.status === "RECIPE_USER_ID_ALREADY_LINKED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
Expand Down
64 changes: 11 additions & 53 deletions lib/build/recipe/accountlinking/recipeImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,22 @@ function getRecipeImplementation(querier, config) {
},
canCreatePrimaryUserId: function ({ recipeUserId }) {
return __awaiter(this, void 0, void 0, function* () {
let result = yield querier.sendGetRequest(
return yield querier.sendGetRequest(
new normalisedURLPath_1.default("/recipe/accountlinking/user/primary/check"),
{
recipeUserId,
}
);
return result;
});
},
createPrimaryUser: function ({ recipeUserId }) {
return __awaiter(this, void 0, void 0, function* () {
let result = yield querier.sendPostRequest(
return yield querier.sendPostRequest(
new normalisedURLPath_1.default("/recipe/accountlinking/user/primary"),
{
recipeUserId,
}
);
return result;
});
},
canLinkAccounts: function ({ recipeUserId, primaryUserId }) {
Expand Down Expand Up @@ -157,59 +155,20 @@ function getRecipeImplementation(querier, config) {
},
unlinkAccounts: function ({ recipeUserId, userContext }) {
return __awaiter(this, void 0, void 0, function* () {
let recipeUserIdToPrimaryUserIdMapping = yield this.getPrimaryUserIdsForRecipeUserIds({
recipeUserIds: [recipeUserId],
userContext,
});
let primaryUserId = recipeUserIdToPrimaryUserIdMapping[recipeUserId];
if (primaryUserId === undefined) {
return {
status: "RECIPE_USER_NOT_FOUND_ERROR",
description: "No user exists with the provided recipeUserId",
};
}
if (primaryUserId === null) {
return {
status: "PRIMARY_USER_NOT_FOUND_ERROR",
description:
"The input recipeUserId is not linked to any primary user, or is not a primary user itself",
};
}
if (primaryUserId === recipeUserId) {
let user = yield this.getUser({
userId: primaryUserId,
userContext,
});
if (user === undefined) {
// this can happen cause of some race condition..
return this.unlinkAccounts({
recipeUserId,
userContext,
});
}
if (user.loginMethods.length > 1) {
// we delete the user here cause if we didn't
// do that, then it would result in the primary user ID having the same
// user ID as the recipe user ID, but they are not linked. So this is not allowed.
yield this.deleteUser({
userId: recipeUserId,
removeAllLinkedAccounts: false,
userContext,
});
return {
status: "OK",
wasRecipeUserDeleted: true,
};
}
}
let accountsUnlinkingResult = yield querier.sendPostRequest(
new normalisedURLPath_1.default("/recipe/accountlinking/user/unlink"),
{
recipeUserId,
primaryUserId,
}
);
if (accountsUnlinkingResult.status === "OK") {
if (accountsUnlinkingResult.status === "OK" && !accountsUnlinkingResult.wasRecipeUserDeleted) {
// we have the !accountsUnlinkingResult.wasRecipeUserDeleted check
// cause if the user was deleted, it means that it's user ID was the
// same as the primary user ID, AND that the primary user ID has more
// than one login method - so if we revoke the session in this case,
// it will revoke the session for all login methods as well (since recipeUserId == primaryUserID).
// The reason we don't do this in the core is that if the user has overriden
// session recipe, it goes through their logic.
yield session_1.default.revokeAllSessionsForUser(recipeUserId, userContext);
}
return accountsUnlinkingResult;
Expand Down Expand Up @@ -240,11 +199,10 @@ function getRecipeImplementation(querier, config) {
},
deleteUser: function ({ userId, removeAllLinkedAccounts }) {
return __awaiter(this, void 0, void 0, function* () {
let result = yield querier.sendPostRequest(new normalisedURLPath_1.default("/user/remove"), {
return yield querier.sendPostRequest(new normalisedURLPath_1.default("/user/remove"), {
userId,
removeAllLinkedAccounts,
});
return result;
});
},
fetchFromAccountToLinkTable: function ({ recipeUserId }) {
Expand Down
Loading