import { Turnkey } from "@turnkey/sdk-server";
import { jwtDecode } from "jwt-decode";
export const turnkeyConfig = {
apiBaseUrl: process.env.TURNKEY_API_URL ?? "",
defaultOrganizationId: process.env.ORGANIZATION_ID ?? "",
apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY ?? "",
apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY ?? "",
};
const turnkey = new Turnkey(turnkeyConfig).apiClient();
async function handleCreateSubOrg(params: Record<string, any>) {
const { email, oauthProviders } = params;
const result = await turnkey.createSubOrganization({
organizationId: turnkeyConfig.defaultOrganizationId,
subOrganizationName: "A social linking suborganization",
rootUsers: [
{
userName: "A suborganization user",
userEmail: email,
oauthProviders,
},
],
rootQuorumThreshold: 1,
wallet: {
walletName: "Default Wallet",
accounts: DEFAULT_ETHEREUM_ACCOUNTS,
},
});
return result;
}
async function handleOAuthLogin(
oidcToken: string,
providerName: string,
publicKey: string,
socialLinking = false
) {
let organizationId: string = turnkeyConfig.defaultOrganizationId;
const { email, iss } =
jwtDecode<{ email?: string; iss?: string }>(oidcToken) || {};
const oauthProviders = [{ providerName, oidcToken }];
const createSuborgParams: Record<string, any> = {
...(socialLinking && email && { email }),
oauthProviders,
};
const { organizationIds: orgIdsOidc } = await turnkey.getSubOrgIds({
filterType: "OIDC_TOKEN",
filterValue: oidcToken,
});
if (orgIdsOidc.length > 0) {
organizationId = orgIdsOidc[0];
} else if (socialLinking && email && iss === "https://accounts.google.com") {
// For Google, first check if there is an organization with the email
const { organizationIds: orgIdsEmail } = await turnkey.getVerifiedSubOrgIds(
{
filterType: "EMAIL",
filterValue: email,
}
);
if (orgIdsEmail.length > 0) {
organizationId = orgIdsEmail[0];
const { users } = await turnkey.getUsers({
organizationId,
});
const userId = users[0].userId;
await turnkey.createOauthProviders({
organizationId,
userId,
oauthProviders: [
{
providerName,
oidcToken,
},
],
});
} else {
const result = await handleCreateSubOrg(createSubOrgParams);
organizationId = result.subOrganizationId;
}
} else {
const result = await handleCreateSubOrg(createSubOrgParams);
organizationId = result.subOrganizationId;
}
const oauthResponse = await turnkey.oauthLogin({
organizationId,
oidcToken,
publicKey,
expirationSeconds: 900,
});
return oauthResponse;
}