+ } />
{/* This shows the login UI on "/auth" route */}
{getSuperTokensRoutesForReactRouterDom(ReactRouter, PreBuiltUIList)}
- {/* This protects the "/" route so that it shows
- only if the user is logged in.
- Else it redirects the user to "/auth" */}
+ {/* This protects the "/dashboard" route so that it shows
+ only if the user is logged in.
+ Else it redirects the user to "/auth" */}
-
+ You're signed in already, check out the Dashboard! 👇
+
+ ) : (
+
Sign-in to continue
+ )}
+
+
+
+
+ >
+ );
+}
diff --git a/boilerplate/fullstack/astro/src/components/Root.tsx b/boilerplate/fullstack/astro-react/src/components/Root.tsx
similarity index 93%
rename from boilerplate/fullstack/astro/src/components/Root.tsx
rename to boilerplate/fullstack/astro-react/src/components/Root.tsx
index 19fa715a..2e1561a8 100644
--- a/boilerplate/fullstack/astro/src/components/Root.tsx
+++ b/boilerplate/fullstack/astro-react/src/components/Root.tsx
@@ -5,7 +5,7 @@ import { SessionAuth } from "supertokens-auth-react/recipe/session/index.js";
SuperTokens.init(frontendConfig());
export default function App({ children }: { children: React.ReactNode }) {
- const isUnprotectedRoute = location.pathname.startsWith("/auth");
+ const isUnprotectedRoute = location.pathname.startsWith("/auth") || location.pathname === "/";
return (
{isUnprotectedRoute ? children : {children}}
diff --git a/boilerplate/fullstack/astro-react/src/config/appInfo.ts b/boilerplate/fullstack/astro-react/src/config/appInfo.ts
new file mode 100644
index 00000000..d4d7e19c
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/appInfo.ts
@@ -0,0 +1,8 @@
+export const appInfo = {
+ // learn more about this on https://supertokens.com/docs/thirdpartyemailpassword/appinfo
+ appName: "SuperTokens Astro demo app",
+ apiDomain: "http://localhost:4321",
+ websiteDomain: "http://localhost:4321",
+ apiBasePath: "/api/auth",
+ websiteBasePath: "/auth",
+};
diff --git a/boilerplate/fullstack/astro-react/src/config/backend.ts b/boilerplate/fullstack/astro-react/src/config/backend.ts
new file mode 100644
index 00000000..eb344e5a
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend.ts
@@ -0,0 +1,24 @@
+import EmailPasswordNode from "supertokens-node/recipe/emailpassword/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+export const backendConfig = (): TypeInput => {
+ return {
+ appInfo,
+ supertokens: {
+ connectionURI: "https://try.supertokens.io",
+ },
+ recipeList: [],
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/all_auth.ts b/boilerplate/fullstack/astro-react/src/config/backend/all_auth.ts
new file mode 100644
index 00000000..42c9fcb2
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/all_auth.ts
@@ -0,0 +1,99 @@
+import EmailPasswordNode from "supertokens-node/recipe/emailpassword/index.js";
+import ThirdPartyNode from "supertokens-node/recipe/thirdparty/index.js";
+import PasswordlessNode from "supertokens-node/recipe/passwordless/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [
+ EmailPasswordNode.init(),
+ ThirdPartyNode.init({
+ signInAndUpFeature: {
+ providers: [
+ // We have provided you with development keys which you can use for testing.
+ // IMPORTANT: Please replace them with your own OAuth keys for production use.
+ {
+ config: {
+ thirdPartyId: "google",
+ clients: [
+ {
+ clientId:
+ "1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
+ clientSecret: "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",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "github",
+ clients: [
+ {
+ clientId: "467101b197249757c71f",
+ clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "apple",
+ clients: [
+ {
+ clientId: "4398792-io.supertokens.example.service",
+ additionalConfig: {
+ keyId: "7M48Y4RYDL",
+ privateKey:
+ "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
+ teamId: "YWQCXGJRJL",
+ },
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "twitter",
+ clients: [
+ {
+ clientId: "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
+ clientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ }),
+ PasswordlessNode.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ flowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
+ }),
+ SessionNode.init(),
+ Dashboard.init(),
+ UserRoles.init(),
+ ],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/emailpassword.ts b/boilerplate/fullstack/astro-react/src/config/backend/emailpassword.ts
new file mode 100644
index 00000000..b8563dfa
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/emailpassword.ts
@@ -0,0 +1,30 @@
+import EmailPasswordNode from "supertokens-node/recipe/emailpassword/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [EmailPasswordNode.init(), SessionNode.init(), Dashboard.init(), UserRoles.init()],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/multifactorauth.ts b/boilerplate/fullstack/astro-react/src/config/backend/multifactorauth.ts
new file mode 100644
index 00000000..9caad834
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/multifactorauth.ts
@@ -0,0 +1,130 @@
+import ThirdPartyNode from "supertokens-node/recipe/thirdparty/index.js";
+import EmailPasswordNode from "supertokens-node/recipe/emailpassword/index.js";
+import Passwordless from "supertokens-node/recipe/passwordless/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import MultiFactorAuth from "supertokens-node/recipe/multifactorauth/index.js";
+import AccountLinking from "supertokens-node/recipe/accountlinking/index.js";
+import EmailVerification from "supertokens-node/recipe/emailverification/index.js";
+import TOTP from "supertokens-node/recipe/totp/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [
+ EmailPasswordNode.init(),
+ ThirdPartyNode.init({
+ signInAndUpFeature: {
+ providers: [
+ // We have provided you with development keys which you can use for testing.
+ // IMPORTANT: Please replace them with your own OAuth keys for production use.
+ {
+ config: {
+ thirdPartyId: "google",
+ clients: [
+ {
+ clientId:
+ "1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
+ clientSecret: "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",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "github",
+ clients: [
+ {
+ clientId: "467101b197249757c71f",
+ clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "apple",
+ clients: [
+ {
+ clientId: "4398792-io.supertokens.example.service",
+ additionalConfig: {
+ keyId: "7M48Y4RYDL",
+ privateKey:
+ "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
+ teamId: "YWQCXGJRJL",
+ },
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "twitter",
+ clients: [
+ {
+ clientId: "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
+ clientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ }),
+ Passwordless.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ flowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
+ }),
+ EmailVerification.init({
+ mode: "REQUIRED",
+ }),
+ AccountLinking.init({
+ shouldDoAutomaticAccountLinking: async () => ({
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: true,
+ }),
+ }),
+ MultiFactorAuth.init({
+ firstFactors: ["thirdparty", "emailpassword"],
+ override: {
+ functions: (oI) => ({
+ ...oI,
+ getMFARequirementsForAuth: () => [
+ {
+ oneOf: [
+ MultiFactorAuth.FactorIds.TOTP,
+ MultiFactorAuth.FactorIds.OTP_EMAIL,
+ MultiFactorAuth.FactorIds.OTP_PHONE,
+ ],
+ },
+ ],
+ }),
+ },
+ }),
+ TOTP.init(),
+ SessionNode.init(),
+ Dashboard.init(),
+ UserRoles.init(),
+ ],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/passwordless.ts b/boilerplate/fullstack/astro-react/src/config/backend/passwordless.ts
new file mode 100644
index 00000000..df2c32a6
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/passwordless.ts
@@ -0,0 +1,38 @@
+import PasswordlessNode from "supertokens-node/recipe/passwordless/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [
+ PasswordlessNode.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ flowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
+ }),
+ SessionNode.init(),
+ Dashboard.init(),
+ UserRoles.init(),
+ ],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/thirdparty.ts b/boilerplate/fullstack/astro-react/src/config/backend/thirdparty.ts
new file mode 100644
index 00000000..46723e5d
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/thirdparty.ts
@@ -0,0 +1,92 @@
+import ThirdPartyNode from "supertokens-node/recipe/thirdparty/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [
+ ThirdPartyNode.init({
+ signInAndUpFeature: {
+ providers: [
+ // We have provided you with development keys which you can use for testing.
+ // IMPORTANT: Please replace them with your own OAuth keys for production use.
+ {
+ config: {
+ thirdPartyId: "google",
+ clients: [
+ {
+ clientId:
+ "1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
+ clientSecret: "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",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "github",
+ clients: [
+ {
+ clientId: "467101b197249757c71f",
+ clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "apple",
+ clients: [
+ {
+ clientId: "4398792-io.supertokens.example.service",
+ additionalConfig: {
+ keyId: "7M48Y4RYDL",
+ privateKey:
+ "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
+ teamId: "YWQCXGJRJL",
+ },
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "twitter",
+ clients: [
+ {
+ clientId: "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
+ clientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ }),
+ SessionNode.init(),
+ Dashboard.init(),
+ UserRoles.init(),
+ ],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/thirdpartyemailpassword.ts b/boilerplate/fullstack/astro-react/src/config/backend/thirdpartyemailpassword.ts
new file mode 100644
index 00000000..017fdcf5
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/thirdpartyemailpassword.ts
@@ -0,0 +1,94 @@
+import ThirdPartyNode from "supertokens-node/recipe/thirdparty/index.js";
+import EmailPasswordNode from "supertokens-node/recipe/emailpassword/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [
+ EmailPasswordNode.init(),
+ ThirdPartyNode.init({
+ signInAndUpFeature: {
+ providers: [
+ // We have provided you with development keys which you can use for testing.
+ // IMPORTANT: Please replace them with your own OAuth keys for production use.
+ {
+ config: {
+ thirdPartyId: "google",
+ clients: [
+ {
+ clientId:
+ "1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
+ clientSecret: "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",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "github",
+ clients: [
+ {
+ clientId: "467101b197249757c71f",
+ clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "apple",
+ clients: [
+ {
+ clientId: "4398792-io.supertokens.example.service",
+ additionalConfig: {
+ keyId: "7M48Y4RYDL",
+ privateKey:
+ "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
+ teamId: "YWQCXGJRJL",
+ },
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "twitter",
+ clients: [
+ {
+ clientId: "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
+ clientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ }),
+ SessionNode.init(),
+ Dashboard.init(),
+ UserRoles.init(),
+ ],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/backend/thirdpartypasswordless.ts b/boilerplate/fullstack/astro-react/src/config/backend/thirdpartypasswordless.ts
new file mode 100644
index 00000000..b4d2e9b3
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/backend/thirdpartypasswordless.ts
@@ -0,0 +1,97 @@
+import ThirdPartyNode from "supertokens-node/recipe/thirdparty/index.js";
+import PasswordlessNode from "supertokens-node/recipe/passwordless/index.js";
+import SessionNode from "supertokens-node/recipe/session/index.js";
+import Dashboard from "supertokens-node/recipe/dashboard/index.js";
+import UserRoles from "supertokens-node/recipe/userroles/index.js";
+import { appInfo } from "./appInfo";
+import { type TypeInput } from "supertokens-node/types";
+import SuperTokens from "supertokens-node";
+
+export let backendConfig = (): TypeInput => {
+ return {
+ supertokens: {
+ // this is the location of the SuperTokens core.
+ connectionURI: "https://try.supertokens.com",
+ },
+ appInfo,
+ // recipeList contains all the modules that you want to
+ // use from SuperTokens. See the full list here: https://supertokens.com/docs/guides
+ recipeList: [
+ ThirdPartyNode.init({
+ signInAndUpFeature: {
+ providers: [
+ // We have provided you with development keys which you can use for testing.
+ // IMPORTANT: Please replace them with your own OAuth keys for production use.
+ {
+ config: {
+ thirdPartyId: "google",
+ clients: [
+ {
+ clientId:
+ "1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
+ clientSecret: "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",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "github",
+ clients: [
+ {
+ clientId: "467101b197249757c71f",
+ clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd",
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "apple",
+ clients: [
+ {
+ clientId: "4398792-io.supertokens.example.service",
+ additionalConfig: {
+ keyId: "7M48Y4RYDL",
+ privateKey:
+ "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
+ teamId: "YWQCXGJRJL",
+ },
+ },
+ ],
+ },
+ },
+ {
+ config: {
+ thirdPartyId: "twitter",
+ clients: [
+ {
+ clientId: "4398792-WXpqVXRiazdRMGNJdEZIa3RVQXc6MTpjaQ",
+ clientSecret: "BivMbtwmcygbRLNQ0zk45yxvW246tnYnTFFq-LH39NwZMxFpdC",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ }),
+ PasswordlessNode.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ flowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
+ }),
+ SessionNode.init(),
+ Dashboard.init(),
+ UserRoles.init(),
+ ],
+ isInServerlessEnv: true,
+ framework: "custom",
+ };
+};
+
+let initialized = false;
+export function ensureSuperTokensInit() {
+ if (!initialized) {
+ SuperTokens.init(backendConfig());
+ initialized = true;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend.ts b/boilerplate/fullstack/astro-react/src/config/frontend.ts
new file mode 100644
index 00000000..5d05dd4f
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend.ts
@@ -0,0 +1,16 @@
+// This file is responsible for bootstrapping your Remix application on the client-side. It typically imports the necessary dependencies and initializes the client-side rendering environment. In this file, you might initialize client-side libraries, set up event listeners, or perform any other client-specific initialization tasks. It's the starting point for client-side code execution.
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { type SuperTokensConfig } from "supertokens-auth-react/lib/build/types";
+
+export const frontendConfig = (): SuperTokensConfig => {
+ return {
+ appInfo,
+ recipeList: [],
+ };
+};
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/thirdpartyemailpassword/introduction",
+};
+
+export const PreBuiltUIList = [];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/all_auth.ts b/boilerplate/fullstack/astro-react/src/config/frontend/all_auth.ts
new file mode 100644
index 00000000..ef2e4387
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/all_auth.ts
@@ -0,0 +1,50 @@
+import EmailPasswordReact from "supertokens-auth-react/recipe/emailpassword/index.js";
+import ThirdPartyReact from "supertokens-auth-react/recipe/thirdparty/index.js";
+import PasswordlessReact from "supertokens-auth-react/recipe/passwordless/index.js";
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui.js";
+import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui.js";
+import { EmailPasswordPreBuiltUI } from "supertokens-auth-react/recipe/emailpassword/prebuiltui";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [
+ EmailPasswordReact.init(),
+ ThirdPartyReact.init({
+ signInAndUpFeature: {
+ providers: [
+ ThirdPartyReact.Github.init(),
+ ThirdPartyReact.Google.init(),
+ ThirdPartyReact.Apple.init(),
+ ],
+ },
+ }),
+ PasswordlessReact.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ }),
+ Session.init(),
+ ],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/thirdpartypasswordless/introduction",
+};
+
+export const PreBuiltUIList = [EmailPasswordPreBuiltUI, ThirdPartyPreBuiltUI, PasswordlessPreBuiltUI];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/emailpassword.ts b/boilerplate/fullstack/astro-react/src/config/frontend/emailpassword.ts
new file mode 100644
index 00000000..d8a3e427
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/emailpassword.ts
@@ -0,0 +1,31 @@
+import EmailPasswordReact from "supertokens-auth-react/recipe/emailpassword/index.js";
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { EmailPasswordPreBuiltUI } from "supertokens-auth-react/recipe/emailpassword/prebuiltui.js";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [EmailPasswordReact.init(), Session.init()],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/emailpassword/introduction",
+};
+
+export const PreBuiltUIList = [EmailPasswordPreBuiltUI];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/multifactorauth.ts b/boilerplate/fullstack/astro-react/src/config/frontend/multifactorauth.ts
new file mode 100644
index 00000000..956cabeb
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/multifactorauth.ts
@@ -0,0 +1,66 @@
+import ThirdPartyReact from "supertokens-auth-react/recipe/thirdparty/index.js";
+import EmailPasswordReact from "supertokens-auth-react/recipe/emailpassword/index.js";
+import MultiFactorAuthReact from "supertokens-auth-react/recipe/multifactorauth/index.js";
+import EmailVerification from "supertokens-auth-react/recipe/emailverification/index.js";
+import PasswordlessReact from "supertokens-auth-react/recipe/passwordless/index.js";
+import TOTPReact from "supertokens-auth-react/recipe/totp/index.js";
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui.js";
+import { EmailPasswordPreBuiltUI } from "supertokens-auth-react/recipe/emailpassword/prebuiltui.js";
+import { MultiFactorAuthPreBuiltUI } from "supertokens-auth-react/recipe/multifactorauth/prebuiltui.js";
+import { EmailVerificationPreBuiltUI } from "supertokens-auth-react/recipe/emailverification/prebuiltui.js";
+import { TOTPPreBuiltUI } from "supertokens-auth-react/recipe/totp/prebuiltui.js";
+import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui.js";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [
+ EmailPasswordReact.init(),
+ ThirdPartyReact.init({
+ signInAndUpFeature: {
+ providers: [
+ ThirdPartyReact.Google.init(),
+ ThirdPartyReact.Github.init(),
+ ThirdPartyReact.Apple.init(),
+ ],
+ },
+ }),
+ PasswordlessReact.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ }),
+ EmailVerification.init({ mode: "REQUIRED" }),
+ MultiFactorAuthReact.init({ firstFactors: ["thirdparty", "emailpassword"] }),
+ TOTPReact.init(),
+ Session.init(),
+ ],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/mfa/introduction",
+};
+
+export const PreBuiltUIList = [
+ ThirdPartyPreBuiltUI,
+ EmailPasswordPreBuiltUI,
+ PasswordlessPreBuiltUI,
+ MultiFactorAuthPreBuiltUI,
+ EmailVerificationPreBuiltUI,
+ TOTPPreBuiltUI,
+];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/passwordless.ts b/boilerplate/fullstack/astro-react/src/config/frontend/passwordless.ts
new file mode 100644
index 00000000..8bb40c15
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/passwordless.ts
@@ -0,0 +1,36 @@
+import PasswordlessReact from "supertokens-auth-react/recipe/passwordless/index.js";
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui.js";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [
+ PasswordlessReact.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ }),
+ Session.init(),
+ ],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/passwordless/introduction",
+};
+
+export const PreBuiltUIList = [PasswordlessPreBuiltUI];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/thirdparty.ts b/boilerplate/fullstack/astro-react/src/config/frontend/thirdparty.ts
new file mode 100644
index 00000000..e5103ca1
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/thirdparty.ts
@@ -0,0 +1,42 @@
+import ThirdPartyReact from "supertokens-auth-react/recipe/thirdparty/index.js";
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui.js";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [
+ ThirdPartyReact.init({
+ signInAndUpFeature: {
+ providers: [
+ ThirdPartyReact.Google.init(),
+ ThirdPartyReact.Github.init(),
+ ThirdPartyReact.Apple.init(),
+ ],
+ },
+ }),
+ Session.init(),
+ ],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/thirdparty/introduction",
+};
+
+export const PreBuiltUIList = [ThirdPartyPreBuiltUI];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/thirdpartyemailpassword.ts b/boilerplate/fullstack/astro-react/src/config/frontend/thirdpartyemailpassword.ts
new file mode 100644
index 00000000..3248f9c1
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/thirdpartyemailpassword.ts
@@ -0,0 +1,41 @@
+import ThirdParty, { Twitter, Apple, Github, Google } from "supertokens-auth-react/recipe/thirdparty";
+import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
+import Session from "supertokens-auth-react/recipe/session";
+import { appInfo } from "./appInfo";
+import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui";
+import { EmailPasswordPreBuiltUI } from "supertokens-auth-react/recipe/emailpassword/prebuiltui";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [
+ EmailPassword.init(),
+ ThirdParty.init({
+ signInAndUpFeature: {
+ providers: [Github.init(), Google.init(), Apple.init(), Twitter.init()],
+ },
+ }),
+ Session.init(),
+ ],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/thirdpartyemailpassword/introduction",
+};
+
+export const PreBuiltUIList = [ThirdPartyPreBuiltUI, EmailPasswordPreBuiltUI];
diff --git a/boilerplate/fullstack/astro-react/src/config/frontend/thirdpartypasswordless.ts b/boilerplate/fullstack/astro-react/src/config/frontend/thirdpartypasswordless.ts
new file mode 100644
index 00000000..70d9dc88
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/config/frontend/thirdpartypasswordless.ts
@@ -0,0 +1,47 @@
+import ThirdPartyReact from "supertokens-auth-react/recipe/thirdparty/index.js";
+import PasswordlessReact from "supertokens-auth-react/recipe/passwordless/index.js";
+import Session from "supertokens-auth-react/recipe/session/index.js";
+import { appInfo } from "./appInfo";
+import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui.js";
+import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui.js";
+
+export const getApiDomain = () => {
+ return appInfo.apiDomain;
+};
+
+export const getWebsiteDomain = () => {
+ return appInfo.websiteDomain;
+};
+
+export const frontendConfig = () => {
+ return {
+ appInfo,
+ recipeList: [
+ ThirdPartyReact.init({
+ signInAndUpFeature: {
+ providers: [
+ ThirdPartyReact.Github.init(),
+ ThirdPartyReact.Google.init(),
+ ThirdPartyReact.Apple.init(),
+ ],
+ },
+ }),
+ PasswordlessReact.init({
+ contactMethod: "EMAIL_OR_PHONE",
+ }),
+ Session.init(),
+ ],
+ getRedirectionURL: async (context) => {
+ if (context.action === "SUCCESS") {
+ return "/dashboard";
+ }
+ return undefined;
+ },
+ };
+};
+
+export const recipeDetails = {
+ docsLink: "https://supertokens.com/docs/thirdpartypasswordless/introduction",
+};
+
+export const PreBuiltUIList = [ThirdPartyPreBuiltUI, PasswordlessPreBuiltUI];
diff --git a/boilerplate/fullstack/astro-react/src/env.d.ts b/boilerplate/fullstack/astro-react/src/env.d.ts
new file mode 100644
index 00000000..61a7b230
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/env.d.ts
@@ -0,0 +1,13 @@
+///
+
+interface Session {
+ accessTokenPayload: any;
+ hasToken: boolean;
+ error: any;
+}
+
+declare namespace App {
+ interface Locals {
+ session: Session;
+ }
+}
diff --git a/boilerplate/fullstack/astro-react/src/layouts/Base.astro b/boilerplate/fullstack/astro-react/src/layouts/Base.astro
new file mode 100644
index 00000000..b775a390
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/layouts/Base.astro
@@ -0,0 +1,57 @@
+---
+import Root from "../components/Root";
+import "../styles/app.css";
+---
+
+
+
+
+
+
+ Astro SuperTokens demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/boilerplate/fullstack/astro-react/src/pages/api/auth.ts b/boilerplate/fullstack/astro-react/src/pages/api/auth.ts
new file mode 100644
index 00000000..237e662a
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/api/auth.ts
@@ -0,0 +1,18 @@
+import { ensureSuperTokensInit } from "../../config/backend";
+import { handleAuthAPIRequest } from "supertokens-node/custom";
+import type { APIRoute } from "astro";
+
+const handleCall = handleAuthAPIRequest();
+
+export const ALL: APIRoute = async ({ request }) => {
+ ensureSuperTokensInit();
+
+ try {
+ return await handleCall(request);
+ } catch (error) {
+ console.error(error);
+ return new Response(JSON.stringify({ error: "Internal server error" }), {
+ status: 500,
+ });
+ }
+};
diff --git a/boilerplate/fullstack/astro-react/src/pages/api/auth/[...path]/[...route].ts b/boilerplate/fullstack/astro-react/src/pages/api/auth/[...path]/[...route].ts
new file mode 100644
index 00000000..a46b10b8
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/api/auth/[...path]/[...route].ts
@@ -0,0 +1,18 @@
+import { ensureSuperTokensInit } from "../../../../config/backend";
+import { handleAuthAPIRequest } from "supertokens-node/custom";
+import type { APIRoute } from "astro";
+
+const handleCall = handleAuthAPIRequest();
+
+export const ALL: APIRoute = async ({ request }) => {
+ ensureSuperTokensInit();
+
+ try {
+ return await handleCall(request);
+ } catch (error) {
+ console.error(error);
+ return new Response(JSON.stringify({ error: "Internal server error" }), {
+ status: 500,
+ });
+ }
+};
diff --git a/boilerplate/fullstack/astro-react/src/pages/api/auth/[...route].ts b/boilerplate/fullstack/astro-react/src/pages/api/auth/[...route].ts
new file mode 100644
index 00000000..66f1a97e
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/api/auth/[...route].ts
@@ -0,0 +1,18 @@
+import { ensureSuperTokensInit } from "../../../config/backend";
+import { handleAuthAPIRequest } from "supertokens-node/custom";
+import type { APIRoute } from "astro";
+
+const handleCall = handleAuthAPIRequest();
+
+export const ALL: APIRoute = async ({ request }) => {
+ ensureSuperTokensInit();
+
+ try {
+ return await handleCall(request);
+ } catch (error) {
+ console.error(error);
+ return new Response(JSON.stringify({ error: "Internal server error" }), {
+ status: 500,
+ });
+ }
+};
diff --git a/boilerplate/fullstack/astro-react/src/pages/api/ping.ts b/boilerplate/fullstack/astro-react/src/pages/api/ping.ts
new file mode 100644
index 00000000..428697b3
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/api/ping.ts
@@ -0,0 +1,10 @@
+import type { APIRoute } from "astro";
+
+export const GET: APIRoute = async () => {
+ return new Response(JSON.stringify({ message: "pong" }), {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+};
diff --git a/boilerplate/fullstack/astro-react/src/pages/api/sessioninfo.ts b/boilerplate/fullstack/astro-react/src/pages/api/sessioninfo.ts
new file mode 100644
index 00000000..e6565821
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/api/sessioninfo.ts
@@ -0,0 +1,29 @@
+import type { APIRoute } from "astro";
+import { getSessionForSSR } from "supertokens-node/custom";
+
+export const GET: APIRoute = async ({ request }) => {
+ const { accessTokenPayload, hasToken, error } = await getSessionForSSR(request);
+
+ if (!hasToken || error) {
+ return new Response(JSON.stringify({ error: "Unauthorized" }), {
+ status: 401,
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ }
+
+ return new Response(
+ JSON.stringify({
+ sessionHandle: accessTokenPayload.sessionHandle,
+ userId: accessTokenPayload.sub,
+ accessTokenPayload,
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+};
diff --git a/boilerplate/fullstack/astro-react/src/pages/auth.astro b/boilerplate/fullstack/astro-react/src/pages/auth.astro
new file mode 100644
index 00000000..6c0f44c4
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/auth.astro
@@ -0,0 +1,8 @@
+---
+import Base from "../layouts/Base.astro";
+import AuthComponent from "../components/Auth";
+---
+
+
+
+
diff --git a/boilerplate/fullstack/astro-react/src/pages/auth/[...path]/[...route].astro b/boilerplate/fullstack/astro-react/src/pages/auth/[...path]/[...route].astro
new file mode 100644
index 00000000..93c16a97
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/auth/[...path]/[...route].astro
@@ -0,0 +1,8 @@
+---
+import Base from "../../../layouts/Base.astro";
+import AuthComponent from "../../../components/Auth";
+---
+
+
+
+
diff --git a/boilerplate/fullstack/astro-react/src/pages/auth/[...route].astro b/boilerplate/fullstack/astro-react/src/pages/auth/[...route].astro
new file mode 100644
index 00000000..724e4da9
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/auth/[...route].astro
@@ -0,0 +1,8 @@
+---
+import Base from "../../layouts/Base.astro";
+import AuthComponent from "../../components/Auth";
+---
+
+
+
+
diff --git a/boilerplate/fullstack/astro-react/src/pages/dashboard.astro b/boilerplate/fullstack/astro-react/src/pages/dashboard.astro
new file mode 100644
index 00000000..8902c12c
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/dashboard.astro
@@ -0,0 +1,10 @@
+---
+import Base from "../layouts/Base.astro";
+import DashboardContent from "../components/Dashboard";
+---
+
+
+
+
\ No newline at end of file
diff --git a/boilerplate/fullstack/astro-react/src/pages/index.astro b/boilerplate/fullstack/astro-react/src/pages/index.astro
new file mode 100644
index 00000000..4c347da1
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/pages/index.astro
@@ -0,0 +1,8 @@
+---
+import Base from "../layouts/Base.astro";
+import Home from "../components/Home.tsx";
+---
+
+
+
+
diff --git a/boilerplate/fullstack/astro-react/src/styles/app.css b/boilerplate/fullstack/astro-react/src/styles/app.css
new file mode 100644
index 00000000..d73bc9c1
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/src/styles/app.css
@@ -0,0 +1,179 @@
+/* Base styles */
+:root {
+ --primary-color: #ff9933;
+ --primary-hover: #ff8a15;
+ --success-color: #3eb655;
+ --success-bg: #e7ffed;
+ --border-color: #e0e0e0;
+}
+
+@font-face {
+ font-family: Menlo;
+ src: url("./assets/fonts/MenloRegular.ttf");
+}
+
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
+ "Droid Sans", "Helvetica Neue", sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+/* Layout */
+.app-container {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ min-height: 100vh;
+ font-family: Rubik, sans-serif;
+}
+
+.fill {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ flex: 1;
+}
+
+/* Header */
+header {
+ border-bottom: 2px solid var(--border-color);
+ padding: 8px;
+}
+
+header nav {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+}
+
+header img {
+ width: 40px;
+}
+
+header ul {
+ display: flex;
+ gap: 12px;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+header a {
+ color: var(--primary-color);
+ font-weight: 600;
+ text-decoration: none;
+}
+
+header a:hover {
+ color: var(--primary-hover);
+}
+
+/* Home page */
+#home-container {
+ align-items: center;
+ min-height: calc(100vh - 58px);
+ background: url("./assets/images/background.png") center/cover;
+}
+
+.logos {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ padding-bottom: 80px;
+}
+
+.logos span {
+ font-size: 8rem;
+ font-weight: bold;
+}
+
+.logos img {
+ height: 240px;
+ width: auto;
+}
+
+/* Main content */
+.main-container {
+ box-shadow: 0 0 60px rgba(0, 0, 0, 0.16);
+ width: min(635px, calc(100% - 24px));
+ border-radius: 16px;
+ margin-bottom: 159px;
+ background-color: white;
+}
+
+.success-title {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 26px;
+ background-color: var(--success-bg);
+ color: var(--success-color);
+ font-size: 20px;
+ line-height: 1;
+}
+
+.success-title img {
+ margin-right: 8px;
+}
+
+.inner-content {
+ padding: 48px;
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+/* User ID display */
+#user-id {
+ position: relative;
+ width: min(430px, calc(100% - 30px));
+ margin: 11px auto 23px;
+ padding: 14px 17px;
+ border-radius: 9px;
+ font-family: Menlo, monospace;
+ line-height: 1;
+ cursor: text;
+ border: 3px solid var(--primary-color);
+}
+
+/* Buttons and navigation */
+.buttons {
+ display: flex;
+ gap: 4px;
+}
+
+.dashboard-button {
+ padding: 8px 13px;
+ background: var(--primary-color);
+ border: 1px solid var(--primary-hover);
+ border-radius: 6px;
+ box-shadow: 0 3px 6px rgba(255, 153, 51, 0.16);
+ color: white;
+ font-weight: bold;
+ font-size: 16px;
+ cursor: pointer;
+ text-decoration: none;
+}
+
+/* Footer */
+footer {
+ padding: 10px;
+}
+
+footer a {
+ color: var(--primary-color);
+ font-weight: 600;
+ /* text-decoration: none; */
+}
+
+footer a:hover {
+ color: var(--primary-hover);
+}
diff --git a/boilerplate/fullstack/astro-react/tsconfig.json b/boilerplate/fullstack/astro-react/tsconfig.json
new file mode 100644
index 00000000..a1b4217e
--- /dev/null
+++ b/boilerplate/fullstack/astro-react/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "astro/tsconfigs/strict",
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "jsxImportSource": "react",
+ "lib": ["ES2015"]
+ }
+}
diff --git a/boilerplate/fullstack/astro/README.md b/boilerplate/fullstack/astro/README.md
index bdebb658..c71af6cc 100644
--- a/boilerplate/fullstack/astro/README.md
+++ b/boilerplate/fullstack/astro/README.md
@@ -1,141 +1,122 @@
-![SuperTokens banner](https://raw.githubusercontent.com/supertokens/supertokens-logo/master/images/Artboard%20%E2%80%93%2027%402x.png)
-
-# SuperTokens with Astro
-
-This demo app demonstrates how to integrate SuperTokens into an Astro application.
-
-Features:
-
-- Initializes SuperTokens with frontend and backend configurations
-- Creates a frontend page to handle authentication-related tasks
-- Integrates the SuperTokens' pre-built login UI for secure user authentication
-- Protects frontend to ensure only authenticated users can access the dashboard
-- Exposes the SuperTokens authentication APIs used by frontend widgets
-
-## Project structure
-
-```txt
-📦[your-app-name]
-┣ 📂public
-┃ ┣ 📂assets
-┃ ┃ ┣ 📂fonts
-┃ ┃ ┗ 📂images
-┃ ┗ 📜favicon.svg
-┣ 📂src
-┃ ┣ 📂components
-┃ ┃ ┣ 📜Auth.tsx
-┃ ┃ ┣ 📜Home.tsx
-┃ ┃ ┣ 📜Root.tsx
-┃ ┃ ┣ 📜sessionAuthForAstro.tsx
-┃ ┃ ┗ 📜tryRefreshClientComponent.tsx
-┃ ┣ 📂layouts
-┃ ┃ ┗ 📜Base.astro
-┃ ┣ 📂config
-┃ ┃ ┣ 📜appInfo.tsx
-┃ ┃ ┣ 📜backend.tsx
-┃ ┃ ┗ 📜frontend.tsx
-┃ ┣ 📂pages
-┃ ┃ ┣ 📂auth
-┃ ┃ ┃ ┣ 📂[...path]
-┃ ┃ ┃ ┃ ┗ 📜[...route].astro
-┃ ┃ ┃ ┗ 📜[...route].astro
-┃ ┃ ┣ 📂api
-┃ ┃ ┃ ┣ 📂auth
-┃ ┃ ┃ ┃ ┣ 📂[...path]
-┃ ┃ ┃ ┃ ┃ ┗ 📜[...route].ts
-┃ ┃ ┃ ┃ ┗ 📜[...route].ts
-┃ ┃ ┣ 📜auth.astro
-┃ ┃ ┣ 📜index.astro
-┃ ┃ ┗ 📜sessioninfo.ts
-┃ ┣ 📂styles
-┃ ┃ ┗ 📜app.css
-┃ ┣ 📜env.d.ts
-┃ ┗ 📜superTokensHelpers.ts
-┣ 📜astro.config.mjs
-┣ 📜package.json
-┣ 📜README.md
-┗ 📜tsconfig.json
+# SuperTokens + Astro
+
+A demo implementation of [SuperTokens](https://supertokens.com/) with [Astro](https://astro.build/), using SuperTokens' prebuilt UI.
+
+## General Info
+
+This project aims to demonstrate how to integrate SuperTokens into an Astro application using our prebuilt UI. Its primary purpose is to serve as an educational tool, but it can also be used as a starting point for your own project.
+
+## Repo Structure
+
+### Source
+
+```
+📦src
+┣ 📂components
+┃ ┣ 📜auth.astro --> Astro component for auth UI
+┃ ┗ 📜dashboard.astro --> Astro component for dashboard functionality
+┣ 📂config
+┃ ┣ 📜appInfo.ts --> App info / config, reused across both frontend and backend
+┃ ┗ 📜frontend.ts --> Frontend config
+┃ ┗ 📜backend.ts --> Backend config
+┣ 📂layouts
+┃ ┗ 📜Base.astro --> Common layout with header and footer
+┣ 📂pages
+┃ ┣ 📂auth
+┃ ┣ ┣ 📂[...path]
+┃ ┃ ┃ ┗ 📜[...route].astro --> Auth routes
+┃ ┃ ┗ 📜[...route].astro --> Auth routes
+┃ ┣ 📂api
+┃ ┃ ┣ 📜 auth.ts --> Auth request handler
+┃ ┃ ┣ 📜 ping.ts --> Public API endpoint
+┃ ┃ ┣ 📜 sessioninfo.ts --> Protected API endpoint
+┃ ┃ ┗ 📂auth
+┃ ┃ ┣ 📂[...path]
+┃ ┃ ┃ ┗ 📜[...route].ts --> Auth request handler
+┃ ┃ ┗ 📜[...route].ts --> Auth request handler
+┃ ┣ 📜auth.astro --> Main auth page
+┃ ┣ 📜dashboard.astro --> Protected dashboard page
+┃ ┗ 📜index.astro --> Public landing page
+┣ 📂styles
+┃ ┗ 📜app.css --> Global styles
+┗ 📜env.d.ts --> TypeScript declarations
```
-Let's explore the important files:
+> Note: the nested routes are required due to how Astro handles routing, and how SuperTokens expects wildcard routes.
-| Directory/File | Description |
-| -------------- | -------------------------------------------------------------------------------------- |
-| **src** | Contains configuration files, pages and components for your application. |
-| **src/config** | Contains configuration files for your application. |
-| | `appInfo.tsx` : Includes information about your application reused throughout the app. |
-| | `backend.tsx` : Backend-related configuration, including settings for SuperTokens. |
-| | `frontend.tsx` : Frontend configuration, including settings for SuperTokens. |
-| **pages** | Contains route files for your application. |
-| | `index.astro` : Represents the default route or landing page. |
-| | `auth.astro` : Shows the pre-built auth UI |
-| | `auth/...` : Deals with authentication callbacks using SuperTokens. |
-| | `supertokens/...` : Deals with authentication routes or components using SuperTokens. |
+### Config
-## Run application locally
+#### Astro
-Follow the steps outlined below to run the application locally:
+The project is a standard Astro application.
-1. Change directory to the **[your-app-name]** folder.
+You can customize the Astro configuration in `astro.config.mjs`. Refer to the [Astro configuration docs](https://docs.astro.build/en/reference/configuration-reference/) for more options.
- ```shell
- cd your-app-name
- ```
+#### SuperTokens
-2. Run the application with the command below:
+SuperTokens configuration is managed through recipe-specific files in the `config/` directory. Each recipe comes in two parts (due to Astro being treated as a full-stack framework):
- ```shell
- npm run dev
- ```
+- `frontend.ts` - Frontend config
+- `backend.ts` - Backend config
-## How to use
+The `appInfo.ts` file is used to configure the app info / config, and is reused across both frontend and backend.
-### Using `create-supertokens-app`
+## Application Flow
-- Run the following command
+The application uses Astro's file-based routing and consists of four main parts:
-```bash
-npx create-supertokens-app@latest --frontend=astro
-```
+1. **Entry Point (`index.astro`)**
-- Follow the instructions on screen
+ - Public landing page
+ - Navigation to auth and dashboard
+ - Project information display
-### Specific Astro considerations for the pre-built UI method using React directly
+2. **Auth Routes (`/auth/*`)**
-Since this demo is using out [pre-built UI](https://supertokens.com/docs/thirdpartyemailpassword/pre-built-ui/setup/frontend), it relies heavily on React. As such, in order to customize the auth and protected / unprotected routes behavior, take a look at the Root component in `src/components/Root.tsx`. The Root component is used in the `src/layouts/Base.astro` layout file, which is used in all demo pages.
+ - Handles all authentication flows using React components
+ - Uses SuperTokens' pre-built UI
+ - Manages login, signup, and password reset
+ - Social login integration (when configured)
-In order to create a public route, you can either customize the `isUnprotectedRoute` behavior in the Root component:
+3. **Protected Dashboard (`/dashboard`)**
-```tsx
-const unprotectedRoutes = ["/auth", "/my-public-route"];
+ - Only accessible to authenticated users
+ - Displays user information
+ - Provides authenticated functionality
+ - API integration example
-export default function App({ children }: { children: React.ReactNode }) {
- // const isUnprotectedRoute = location.pathname.startsWith("/auth"); -> remove this
- const isUnprotectedRoute = unprotectedRoutes.some((route) => location.pathname.startsWith(route));
+4. **API Routes (`/api/*`)**
+ - Protected session info endpoint
+ - Public ping endpoint
+ - Server-side session validation
- return (
- {isUnprotectedRoute ? children : {children}}
- );
-}
-```
+When a user visits the application, they start at the home page (`/`). They can choose to authenticate through the `/auth` routes, and once authenticated, they gain access to the protected dashboard. The session state is managed throughout the application using SuperTokens' session management.
+
+## Customizations
+
+If you want to customize the default auth UI, you have two options:
+
+1. Refer to the [docs](https://supertokens.com/docs/thirdpartyemailpassword/advanced-customizations/react-component-override/usage) on how to customize the pre-built UI.
+2. Roll your own UI by choosing "Custom UI" in the right sidebar in the [docs](https://supertokens.com/docs/thirdpartyemailpassword/quickstart/frontend-setup).
-or, use your own layout component, but make sure to check whether a session exists if you'd like to protect that route (see `index.astro` for an example, using `getSessionForSSR`).
+## Additional Resources
-### Alternatives
+- Custom UI Astro Example: https://github.com/supertokens/supertokens-web-js/tree/master/examples/astro/with-thirdpartyemailpassword
+- Custom UI Blog post: https://supertokens.medium.com/adding-social-login-to-your-website-with-supertokens-custom-ui-only-5fa4d7ab6402
+- Awesome SuperTokens: https://github.com/kohasummons/awesome-supertokens
-If you'd like a more low-level approach, you can go for a custom UI setup. This amount to using our SDK methods with your UI - you can find an example [here](https://github.com/supertokens/supertokens-web-js/tree/master/examples/astro/with-thirdpartyemailpassword).
+## Contributing
-If you'd like a simpler setup, you can use our universal pre-built UI. It's still build on React, but it doesn't explicitly depend on having React in your project. As a result, you only have to provide some routess and a div element to render the UI in. You can find an example [here]().
+Please refer to the [CONTRIBUTING.md](https://github.com/supertokens/create-supertokens-app/blob/master/CONTRIBUTING.md) file in the root of the [`create-supertokens-app`](https://github.com/supertokens/create-supertokens-app) repo.
-## Author
+## Contributing
-Created with :heart: by the folks at supertokens.com.
+Please refer to the [CONTRIBUTING.md](https://github.com/supertokens/create-supertokens-app/blob/master/CONTRIBUTING.md) file in the root of the [`create-supertokens-app`](https://github.com/supertokens/create-supertokens-app) repo.
-## License
+## Contact us
-This project is licensed under the Apache 2.0 license.
+For any questions, or support requests, please email us at team@supertokens.io, or join our [Discord](https://supertokens.io/discord) server.
-## Notes
+## Authors
-- To know more about how this app works and to learn how to customise it based on your use cases refer to the [SuperTokens Documentation](https://supertokens.com/docs/guides)
-- We have provided development OAuth keys for the various built-in third party providers in the `/app/config/backend.ts` file. Feel free to use them for development purposes, but **please create your own keys for production use**.
+Created with :heart: by the folks at SuperTokens.io.
diff --git a/boilerplate/fullstack/astro/astro.config.mjs b/boilerplate/fullstack/astro/astro.config.mjs
index d2c8cc4e..6c79776a 100644
--- a/boilerplate/fullstack/astro/astro.config.mjs
+++ b/boilerplate/fullstack/astro/astro.config.mjs
@@ -1,13 +1,10 @@
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
-import react from "@astrojs/react";
-
// https://astro.build/config
export default defineConfig({
output: "server",
adapter: node({
mode: "standalone",
}),
- integrations: [react()],
});
diff --git a/boilerplate/fullstack/astro/package.json b/boilerplate/fullstack/astro/package.json
index c2b92714..ab70728e 100644
--- a/boilerplate/fullstack/astro/package.json
+++ b/boilerplate/fullstack/astro/package.json
@@ -10,16 +10,10 @@
"dependencies": {
"@astrojs/check": "latest",
"@astrojs/node": "latest",
- "@astrojs/react": "latest",
- "@types/react": "latest",
- "@types/react-dom": "latest",
"astro": "latest",
"cookie": "^0.6.0",
"jose": "^5.9.3",
"jwks-rsa": "^3.1.0",
- "react": "latest",
- "react-dom": "latest",
- "supertokens-auth-react": "latest",
"supertokens-node": "latest",
"supertokens-web-js": "latest"
},
diff --git a/boilerplate/fullstack/astro/public/ST.svg b/boilerplate/fullstack/astro/public/ST.svg
new file mode 100644
index 00000000..30b435bd
--- /dev/null
+++ b/boilerplate/fullstack/astro/public/ST.svg
@@ -0,0 +1,17 @@
+
diff --git a/boilerplate/fullstack/astro/public/astro-icon-dark.svg b/boilerplate/fullstack/astro/public/astro-icon-dark.svg
new file mode 100644
index 00000000..e5211819
--- /dev/null
+++ b/boilerplate/fullstack/astro/public/astro-icon-dark.svg
@@ -0,0 +1,4 @@
+
diff --git a/boilerplate/fullstack/astro/src/components/Home.tsx b/boilerplate/fullstack/astro/src/components/Home.tsx
deleted file mode 100644
index 45f67716..00000000
--- a/boilerplate/fullstack/astro/src/components/Home.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-import { recipeDetails } from "../config/frontend";
-import SuperTokens from "supertokens-auth-react";
-import SessionReact from "supertokens-auth-react/recipe/session/index.js";
-import { TryRefreshComponent } from "../components/tryRefreshClientComponent";
-import { SessionAuthForAstro } from "./sessionAuthForAstro";
-import type { JWTPayload } from "jose";
-
-export default function Home({
- accessTokenPayload,
- hasToken,
- error,
-}: {
- accessTokenPayload: JWTPayload | undefined;
- hasToken: boolean;
- error: Error | undefined;
-}) {
- async function logoutClicked() {
- await SessionReact.signOut();
- SuperTokens.redirectToAuth();
- }
-
- if (error) {
- return
Something went wrong while trying to get the session. Error - {error.message}
;
- }
-
- // `accessTokenPayload` will be undefined if it the session does not exist or has expired
- if (accessTokenPayload === undefined) {
- /**
- * This means that the user is not logged in. If you want to display some other UI in this
- * case, you can do so here.
- */
- if (!hasToken) {
- location.href = "/auth";
- return;
- }
-
- /**
- * This means that the session does not exist but we have session tokens for the user. In this case
- * the `TryRefreshComponent` will try to refresh the session.
- *
- * To learn about why the 'key' attribute is required refer to: https://github.com/supertokens/supertokens-node/issues/826#issuecomment-2092144048
- */
- return ;
- }
-
- const fetchUserData = async () => {
- const userInfoResponse = await fetch("http://localhost:4321/sessioninfo");
-
- alert(JSON.stringify(await userInfoResponse.json()));
- };
-
- const links: {
- name: string;
- link: string;
- icon: string;
- }[] = [
- {
- name: "Blogs",
- link: "https://supertokens.com/blog",
- icon: "/assets/images/blogs-icon.svg",
- },
- {
- name: "Guides",
- link: recipeDetails.docsLink,
- icon: "/assets/images/guide-icon.svg",
- },
- {
- name: "Sign Out",
- link: "",
- icon: "/assets/images/sign-out-icon.svg",
- },
- ];
-
- /**
- * SessionAuthForAstro will handle proper redirection for the user based on the different session states.
- * It will redirect to the login page if the session does not exist etc.
- */
- return (
-
-