Alen
12/08/2022, 5:51 AMsattvikc
12/08/2022, 5:52 AMrp
12/08/2022, 5:56 AMAlen
12/08/2022, 5:58 AMrp
12/08/2022, 9:52 AMAlen
12/08/2022, 9:55 AMsattvikc
12/08/2022, 10:08 AMAlen
12/08/2022, 10:09 AMsattvikc
12/08/2022, 10:20 AMAlen
12/08/2022, 10:22 AMsattvikc
12/08/2022, 10:27 AMAlen
12/08/2022, 10:31 AMsattvikc
12/08/2022, 10:36 AMhd
which can be used to restrict the domain. something like:
ts
GoogleWorkspaces({
clientId: '...',
clientSecret: '...',
hd: 'supertokens.com'
})
Alen
12/08/2022, 10:37 AMsattvikc
12/08/2022, 10:39 AMAlen
12/08/2022, 10:40 AMsattvikc
12/08/2022, 10:41 AMAlen
12/08/2022, 10:43 AMThirdPartyPasswordless.GoogleWorkspaces({
clientId: config.socialAuthConfig.google.googleClientId,
clientSecret: config.socialAuthConfig.google.googleClientSecret,
hd: 'supertokens.com'
}),
I tried this, it listed me with only workspaces emails, but its not throwing any error with other workspace email addresses.sattvikc
12/08/2022, 10:50 AMAlen
12/08/2022, 10:51 AMsattvikc
12/08/2022, 10:51 AMAlen
12/08/2022, 10:52 AMsattvikc
12/08/2022, 10:52 AMAlen
12/08/2022, 10:53 AMsattvikc
12/08/2022, 10:55 AMAlen
12/08/2022, 10:56 AMhd: *
, but I have set hd: 'supertokens.com'
sattvikc
12/08/2022, 11:00 AMAlen
12/08/2022, 11:00 AMSuperTokens.init({
appInfo: {
apiDomain: Constants.SUPERTOKENS_SVC_URL,
apiBasePath: "/auth",
appName: "blocksurvey",
},
recipeList: [
Session.init(),
ThirdPartyPasswordless.init()
],
});
sattvikc
12/08/2022, 11:01 AMAlen
12/08/2022, 11:01 AMsattvikc
12/08/2022, 11:02 AMAlen
12/08/2022, 11:03 AMasync handleThirdPartyAuthCallback() {
try {
const response = await thirdPartySignInAndUp();
if (response.status === "OK") {
if (response.createdNewUser) {
// sign up successful
this.supertokensId = response.user.id;
this.getYourSecretKey();
this.errorMsg = "";
// Add user details to firebase collection
this.emailService.addUserToSupertokensCollectionInFirebase(response.user);
}
} else {
window.alert("No email provided by social sign up. Please use another form of sign up.");
this.emailService.redirectToPage(this.redirectTo, 'signup', this.methods);
}
} catch (err: any) {
if (err.isSuperTokensGeneralError === true) {
// this may be a custom error message sent from the API by you.
window.alert(err.message);
} else {
window.alert("Oops! Something went wrong.");
}
this.emailService.redirectToPage(this.redirectTo, 'signin', this.methods);
}
}
sattvikc
12/08/2022, 11:04 AMAlen
12/08/2022, 11:04 AMasync thirdPartySignUpClicked(provider) {
try {
const authUrl = await getThirdPartyAuthorisationURLWithQueryParamsAndSetState({
providerId: provider,
authorisationURL: Constants.DOMAIN_URL + "/signup",
});
// we redirect the user for auth.
window.location.assign(authUrl);
} catch (err: any) {
if (err.isSuperTokensGeneralError === true) {
// this may be a custom error message sent from the API by you.
window.alert(err.message);
} else {
window.alert("Oops! Something went wrong.");
}
// redirect on failure
this.emailService.redirectToPage(this.redirectTo, 'signup', this.methods);
}
}
sattvikc
12/08/2022, 11:08 AMts
GoogleWorkspaces({
clientId: '...',
clientSecret: '...',
domain: 'supertokens.com'
})
Alen
12/08/2022, 11:13 AMrp
12/08/2022, 11:20 AMAlen
12/08/2022, 11:21 AMsattvikc
12/12/2022, 6:39 AMAlen
12/12/2022, 6:41 AMsattvikc
12/12/2022, 6:44 AMrp
12/12/2022, 6:44 AMAlen
12/12/2022, 6:45 AMrp
12/12/2022, 6:45 AMAlen
12/12/2022, 7:08 AMrp
12/12/2022, 7:15 AMAlen
12/12/2022, 7:16 AMrp
12/12/2022, 7:17 AMAlen
12/12/2022, 7:17 AMrp
12/12/2022, 7:17 AMAlen
12/12/2022, 7:17 AMrp
12/12/2022, 7:18 AMAlen
12/12/2022, 7:19 AMrp
12/12/2022, 8:15 AMAlen
12/12/2022, 8:16 AMrp
12/12/2022, 8:18 AMAlen
12/16/2022, 7:31 AMrp
12/16/2022, 7:31 AMAlen
12/16/2022, 7:33 AMrp
12/16/2022, 7:33 AMid
in frontend and backend is called saml-jackson
, this should also be called that.Alen
12/16/2022, 7:34 AMrp
12/16/2022, 7:35 AMAlen
12/16/2022, 7:37 AM"/recipe/thirdparty/tenant/config"
. Am I correct?rp
12/16/2022, 7:39 AMAlen
12/16/2022, 7:41 AMrp
12/16/2022, 7:43 AMAlen
12/16/2022, 7:48 AMgetThirdPartyAuthorisationURLWithQueryParamsAndSetState()
. do I have to override this function and then send tenant id using usercontext ?const authUrl = await getThirdPartyAuthorisationURLWithQueryParamsAndSetState({
providerId: provider,
providerClientId : 'tenantId',
authorisationURL: Constants.DOMAIN_URL + "/signup",
});
rp
12/16/2022, 8:10 AMAlen
12/16/2022, 8:27 AMconst authUrl = await getThirdPartyAuthorisationURLWithQueryParamsAndSetState({
providerId: provider,
options: {
preAPIHook: async (context: any) => {
let url = new URL(context.url);
let action = context.action;
if (action === 'GET_AUTHORISATION_URL') {
let tenantId = 'test'
localStorage.setItem("saml-tenant-id", tenantId)
url.searchParams.append('tenant', tenantId);
url.searchParams.append('product', 'saml-jackson');
}
if (action === 'THIRD_PARTY_SIGN_IN_UP') {
let tenantId = localStorage.getItem("saml-tenant-id");
url.searchParams.append('tenant', tenantId);
url.searchParams.append('product', 'saml-jackson');
}
return {
requestInit: context.requestInit,
url: url.href,
};
},
},
authorisationURL: Constants.DOMAIN_URL + "/signup",
});
rp
12/16/2022, 8:32 AMGET_AUTHORISATION_URL
since you are just calling that functionAlen
12/16/2022, 8:40 AMlet action = context.action;
this is undefined.rp
12/16/2022, 8:40 AMAlen
12/16/2022, 8:42 AMhttps://2b2279d150ffbe9aaad08e5-us-east-1.aws.supertokens.io:3567/recipe/thirdparty/tenant/config?thirdPartyId=${product}&supertokensTenantId=${tenant}
,
headers: {
'api-key': 'secret',
},
});
let client_id = profile.data.config.client_id;
let client_secret = profile.data.config.client_secret;
input.userContext.client_id = client_id;
input.userContext.client_secret = client_secret;
return originalImplementation.authorisationUrlGET(input);
},`TypeError: Cannot read properties of undefined (reading 'params')
at Object.<anonymous> (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:45:75)
at Generator.next (<anonymous>)
at C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:30:75
at new Promise (<anonymous>)
at __awaiter (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:12:16)
at Object.authorisationUrlGET (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:42:20)
at Object.proxy._call (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-js-override\lib\build\index.js:56:56)
at Object.ret.<computed> [as authorisationUrlGET] (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-js-override\lib\build\getProxyObject.js:27:29)
at Object.authorisationUrlGET (C:\BlockSurvey Projects\blocksurvey-supertoken-function\index.js:408:59)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
index.js:408:59
this line points to return originalImplementation.authorisationUrlGET(input);
rp
12/16/2022, 9:35 AMAlen
12/16/2022, 9:36 AMhttps://7193f3e14ea770f517937-us-east-1.aws.supertokens.io:5125/api/oauth/token
,
params: {
client_id,
client_secret,
grant_type: "authorization_code",
redirect_uri: redirectURI || "",
code: authCodeFromRequest || "",
}
},
...`rp
12/16/2022, 9:38 AMget
function? Oh and also, the get function is not async. So you should remove the async
keywordAlen
12/16/2022, 10:12 AMrp
12/16/2022, 10:12 AMAlen
12/16/2022, 10:15 AMTypeError: Cannot read properties of undefined (reading 'startsWith')
at isUsingDevelopmentClientId (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:199:22)
at Object.<anonymous> (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:90:25)
at Generator.next (<anonymous>)
at C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:30:75
at new Promise (<anonymous>)
at __awaiter (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:12:16)
at Object.signInUpPOST (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-node\lib\build\recipe\thirdparty\api\implementation.js:85:20)
at Object.proxy._call (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-js-override\lib\build\index.js:56:56)
at Object.ret.<computed> [as thirdPartySignInUpPOST] (C:\BlockSurvey Projects\blocksurvey-supertoken-function\node_modules\supertokens-js-override\lib\build\getProxyObject.js:27:29)
at Object.thirdPartySignInUpPOST (C:\BlockSurvey Projects\blocksurvey-supertoken-function\index.js:441:73)
thirdPartySignInUpPOST: async function (input) {
try {
if (originalImplementation.thirdPartySignInUpPOST) {
input.userContext.request = input.options.req.original
return await originalImplementation.thirdPartySignInUpPOST(input);
}
} catch (err) {
if (err.message === "Cannot sign up as email already exists") {
// this error was thrown from our function override above.
// so we send a useful message to the user
return {
status: "GENERAL_ERROR",
message: "Seems like you already have an account with another method. Please use that instead."
}
}
const response = await thirdPartySignInAndUp({
options: {
preAPIHook: async (context: any) => {
let url = new URL(context.url);
let tenantId = 'alen'
localStorage.setItem("saml-tenant-id", tenantId)
url.searchParams.append('tenant', tenantId);
url.searchParams.append('product', 'saml-jackson');
return {
requestInit: context.requestInit,
url: url.href,
};
},
}
rp
12/16/2022, 10:22 AMAlen
12/16/2022, 10:22 AMindex.js:441:73
points at return await originalImplementation.thirdPartySignInUpPOST(input);
rp
12/16/2022, 10:23 AMAlen
12/16/2022, 10:24 AMrp
12/16/2022, 10:26 AMAlen
12/16/2022, 10:26 AMrp
12/16/2022, 10:27 AMAlen
12/16/2022, 10:27 AMrp
12/16/2022, 10:27 AMthirdPartySignInUpPOST
which you have doneAlen
12/16/2022, 10:28 AMthirdPartySignInUpPOST: async function (input) {
try {
if (originalImplementation.thirdPartySignInUpPOST) {
input.userContext.request = input.options.req.original
return await originalImplementation.thirdPartySignInUpPOST(input);
}
} catch (err) {
if (err.message === "Cannot sign up as email already exists") {
// this error was thrown from our function override above.
// so we send a useful message to the user
return {
status: "GENERAL_ERROR",
message: "Seems like you already have an account with another method. Please use that instead."
}
}
rp
12/16/2022, 10:28 AMAlen
12/16/2022, 10:29 AMrp
12/16/2022, 10:30 AMAlen
12/16/2022, 10:31 AMrp
12/16/2022, 10:37 AMAlen
12/16/2022, 10:37 AMrp
12/16/2022, 10:38 AMAlen
12/16/2022, 10:39 AMrp
12/16/2022, 10:39 AMAlen
12/16/2022, 10:40 AMhttps://7193f3e10df3d70f517937-us-east-1.aws.supertokens.io:5225/api/oauth/userinfo
,
headers: {
Authorization: Bearer ${accessTokenAPIResponse.access_token}
,
},
});
return {
id: profile.data.id,
email: {
id: profile.data.email,
isVerified: true
}
};
}`rp
12/16/2022, 10:41 AMid: profile.data.id,
to be something like id: profile.data.id + "|" + tenantId,
and you can get the tenantId from the userContext in the same way of how you get the client_id and secretAlen
12/16/2022, 10:44 AMrp
12/16/2022, 11:41 AMAlen
12/16/2022, 11:49 AMrp
12/16/2022, 11:54 AMAlen
12/16/2022, 11:54 AMdata: {
raw: {
id: '1dda9fb491dc01bd24d2423ba2f22ae561f56ddf2376b29a11c80281d21201f9',
email: 'jackson@example.com',
firstName: 'jackson',
lastName: 'jackson',
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier': 'jackson@example.com'
},
id: '1dda9fb491dc01bd24d2423ba2f22ae561f56ddf2376b29a11c80281d21201f9',
email: 'jackson@example.com',
firstName: 'jackson',
lastName: 'jackson',
idHash: 'e47ade86ba357f1041be45f8477f5b790309b3e7',
requested: {
client_id: '5283edb8634c7ca6c0431a7049cacf0fedba31ef',
state: '74d99b0c7d3f94f1ec290',
redirect_uri: 'http://localhost:4200/signup',
tenant: 'alen1',
product: 'Blocksurvey',
scope: []
}
}
rp
12/16/2022, 12:21 PMprofile.data.email
which is jackson@example.com
in this caseAlen
12/16/2022, 12:22 PMhttps://7193f3e14ef517937-us-east-1.aws.supertokens.io:5225/api/oauth/userinfo
,
headers: {
Authorization: Bearer ${accessTokenAPIResponse.access_token}
,
},
});
console.log(profile);
return {
id: profile.data.id,
email: {
id: profile.data.id + "|" + tenantId,
isVerified: true
}
};`rp
12/16/2022, 12:24 PMid
value:
return {
id: profile.data.id + "|" + tenantId,
email: {
id: profile.data.email,
isVerified: true
}
};
Alen
12/16/2022, 12:24 PM${config.supertokensConfig.connection_url}/recipe/thirdparty/tenant/config?thirdPartyId=${product}&supertokensTenantId=${tenant}
,
headers: {
'api-key': config.supertokensConfig.api_key,
},
});
let client_id = profile.data.config.client_id;
let client_secret = profile.data.config.client_secret;
input.userContext.client_id = client_id;
input.userContext.client_secret = client_secret;
return await originalImplementation.authorisationUrlGET(input);
}
},`rp
12/16/2022, 12:27 PMif (request.query.tenant && request.query.product) {
is not true, you should just call the original implementationAlen
12/16/2022, 12:31 PMrp
12/16/2022, 12:36 PMAlen
12/16/2022, 12:54 PMrp
12/16/2022, 12:59 PM