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

Astro and Solid custom UI examples. #119

Merged
merged 5 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 34 additions & 0 deletions examples/astro/with-thirdpartyemailpassword/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
![SuperTokens banner](https://raw.githubusercontent.com/supertokens/supertokens-logo/master/images/Artboard%20%E2%80%93%2027%402x.png)

# SuperTokens ThirdPartyEmailPassword Demo app for Astro

This demo app demonstrates the following use cases:

- Social Login / Sign up
- Email & Password login
- Logout
- Session management & Calling APIs

## Project setup

Use `npm` to install the project dependencies:

```bash
npm install
```

## Run the demo app

```bash
npm run dev
```

The app will start on `http://localhost:4321`

## Author

Created with :heart: by the folks at supertokens.com.

## License

This project is licensed under the Apache 2.0 license.
11 changes: 11 additions & 0 deletions examples/astro/with-thirdpartyemailpassword/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from "astro/config";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
output: "server",
adapter: node({
mode: "standalone",
}),
});
28 changes: 28 additions & 0 deletions examples/astro/with-thirdpartyemailpassword/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "astro-supertokens",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.9.2",
"@astrojs/node": "^8.3.3",
"astro": "^4.14.2",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.1.0",
"micromatch": "^4.0.7",
"supertokens-node": "^20.0.2",
"supertokens-web-js": "^0.13.0",
"typescript": "^5.5.4"
},
"devDependencies": {
"@types/micromatch": "^4.0.9",
"prettier": "^3.3.3",
"prettier-plugin-astro": "^0.14.1"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
241 changes: 241 additions & 0 deletions examples/astro/with-thirdpartyemailpassword/src/auth/Auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import { signOut, signUp } from "supertokens-web-js/recipe/emailpassword";
import { doesEmailExist } from "supertokens-web-js/recipe/emailpassword";
import { signIn } from "supertokens-web-js/recipe/emailpassword";
import { getAuthorisationURLWithQueryParamsAndSetState } from "supertokens-web-js/recipe/thirdparty";
import { signInAndUp } from "supertokens-web-js/recipe/thirdparty";

export async function handleCallback() {
try {
const response = await signInAndUp();

if (response.status === "OK") {
console.log(response.user);
if (response.createdNewRecipeUser && response.user.loginMethods.length === 1) {
// sign up successful
} else {
// sign in successful
}
window.location.assign("/dashboard");
} else if (response.status === "SIGN_IN_UP_NOT_ALLOWED") {
// the reason string is a user friendly message
// about what went wrong. It can also contain a support code which users
// can tell you so you know why their sign in / up was not allowed.
window.alert(response.reason);
} else {
// SuperTokens requires that the third party provider
// gives an email for the user. If that's not the case, sign up / in
// will fail.

// As a hack to solve this, you can override the backend functions to create a fake email for the user.

window.alert("No email provided by social login. Please use another form of login");
window.location.assign("/"); // redirect back to login page
}
} catch (err: any) {
console.log(err);

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.");
}
}
}

export async function googleSignInClicked() {
try {
const authUrl = await getAuthorisationURLWithQueryParamsAndSetState({
thirdPartyId: "google",

// This is where Google should redirect the user back after login or error.
// This URL goes on the Google's dashboard as well.
frontendRedirectURI: "http://localhost:4321/auth/callback/google",
});

/*
Example value of authUrl: https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&include_granted_scopes=true&response_type=code&client_id=1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com&state=5a489996a28cafc83ddff&redirect_uri=https%3A%2F%2Fsupertokens.io%2Fdev%2Foauth%2Fredirect-to-app&flowName=GeneralOAuthFlow
*/

// we redirect the user to google 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.");
}
}
}

export async function githubSignInClicked() {
try {
const authUrl = await getAuthorisationURLWithQueryParamsAndSetState({
thirdPartyId: "github",

// This is where Google should redirect the user back after login or error.
// This URL goes on the Google's dashboard as well.
frontendRedirectURI: "http://localhost:4321/auth/callback/github",
});

/*
Example value of authUrl: https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&include_granted_scopes=true&response_type=code&client_id=1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com&state=5a489996a28cafc83ddff&redirect_uri=https%3A%2F%2Fsupertokens.io%2Fdev%2Foauth%2Fredirect-to-app&flowName=GeneralOAuthFlow
*/

// we redirect the user to google 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.");
}
}
}

export async function signInClicked(email: string, password: string) {
try {
let response = await signIn({
formFields: [
{
id: "email",
value: email,
},
{
id: "password",
value: password,
},
],
});

if (response.status === "FIELD_ERROR") {
response.formFields.forEach((formField) => {
if (formField.id === "email") {
// Email validation failed (for example incorrect email syntax).
window.alert(formField.error);
}
});
} else if (response.status === "WRONG_CREDENTIALS_ERROR") {
window.alert("Email password combination is incorrect.");
} else if (response.status === "SIGN_IN_NOT_ALLOWED") {
// the reason string is a user friendly message
// about what went wrong. It can also contain a support code which users
// can tell you so you know why their sign in was not allowed.
window.alert(response.reason);
} else {
// sign in successful. The session tokens are automatically handled by
// the frontend SDK.
window.location.href = "/dashboard";
}
} 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.");
}
}
}

export async function checkEmail(email: string) {
try {
let response = await doesEmailExist({
email,
});

if (response.doesExist) {
window.alert("Email already exists. Please sign in instead");
}
} 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.");
}
}
}

export async function signUpClicked(email: string, password: string) {
try {
let response = await signUp({
formFields: [
{
id: "email",
value: email,
},
{
id: "password",
value: password,
},
],
});

if (response.status === "FIELD_ERROR") {
// one of the input formFields failed validation
response.formFields.forEach((formField) => {
if (formField.id === "email") {
// Email validation failed (for example incorrect email syntax),
// or the email is not unique.
window.alert(formField.error);
} else if (formField.id === "password") {
// Password validation failed.
// Maybe it didn't match the password strength
window.alert(formField.error);
}
});
} else if (response.status === "SIGN_UP_NOT_ALLOWED") {
// the reason string is a user friendly message
// about what went wrong. It can also contain a support code which users
// can tell you so you know why their sign up was not allowed.
window.alert(response.reason);
} else {
// sign up successful. The session tokens are automatically handled by
// the frontend SDK.
window.location.href = "/dashboard";
}
} 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.");
}
}
}

export async function signOutClicked() {
try {
await signOut();
window.location.href = "/";
} 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.");
}
}
}

export async function getSessionInfo() {
try {
let response = await fetch("/auth/sessioninfo", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

if (response.status === 200) {
let data = await response.json();
return data;
} else {
window.alert("Oops! Something went wrong.");
}
} catch (err: any) {
window.alert("Oops! Something went wrong.");
}
}
54 changes: 54 additions & 0 deletions examples/astro/with-thirdpartyemailpassword/src/auth/STBEConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import ThirdPartyNode from "supertokens-node/recipe/thirdparty";
import EmailPasswordNode from "supertokens-node/recipe/emailpassword";

import SessionNode from "supertokens-node/recipe/session";
import appInfo from "./appInfo.json";
import { type TypeInput } from "supertokens-node/types";

export const initBE = (): TypeInput => {
return {
framework: "custom",
supertokens: {
// https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
connectionURI: "https://try.supertokens.com",
// apiKey: <API_KEY(if configured)>,
},
appInfo,
recipeList: [
EmailPasswordNode.init(),
ThirdPartyNode.init({
// 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.
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "google",
clients: [
{
clientId:
"1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
clientSecret: "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",
},
],
},
},
{
config: {
thirdPartyId: "github",
clients: [
{
clientId: "467101b197249757c71f",
clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd",
},
],
},
},
],
},
}),
SessionNode.init(),
],
isInServerlessEnv: true,
};
};
12 changes: 12 additions & 0 deletions examples/astro/with-thirdpartyemailpassword/src/auth/STFEConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ThirdPartyWebJs from "supertokens-web-js/recipe/thirdparty";
import EmailPasswordWebJs from "supertokens-web-js/recipe/emailpassword";
import SessionWebJs from "supertokens-web-js/recipe/session";
import appInfo from "./appInfo.json";
import { type SuperTokensConfig } from "supertokens-web-js/types";

export const initFE = (): SuperTokensConfig => {
return {
appInfo,
recipeList: [ThirdPartyWebJs.init(), EmailPasswordWebJs.init(), SessionWebJs.init()],
};
};
Loading
Loading