-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
752a921
commit 2932c33
Showing
53 changed files
with
3,776 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
title: "login" | ||
slug: "login" | ||
excerpt: "Login users with Polyfire Auth" | ||
hidden: false | ||
createdAt: "Wed Sep 27 2023 07:29:51 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:33:49 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
> 📘 Auth is required | ||
> | ||
> All the components and functions in the SDK require you to connect your users to Polyfire Auth. | ||
> | ||
> Because all calls to the Polyfire API use LLMs (and therefore cost money) or access user data, the client needs some kind of secured authentification. | ||
> | ||
> You don't need to authenticate your users entirely through Polyfire (e.g. we can authenticate your Firebase or Supabase user tokens). If you need a custom auth provider integrated, [tell us on Discord](https://discord.polyfire.com). | ||
Login users client-side to create unique user sessions. | ||
|
||
- Works with providers "Google" and "GitHub" but also "Firebase" (see below). | ||
- Must be called to use _models_ and _data_ modules client-side. | ||
|
||
```typescript | ||
export declare function login(input: LoginFunctionInput, projectOptions: { | ||
project: string; | ||
endpoint: string; | ||
}): Promise<void>; | ||
``` | ||
|
||
## Types | ||
|
||
```typescript | ||
type SimpleProvider = "github" | "google"; | ||
type LoginWithFirebaseInput = { | ||
token: string; | ||
provider: "firebase"; | ||
}; | ||
type LoginFunctionInput = SimpleProvider | { | ||
provider: SimpleProvider; | ||
} | LoginWithFirebaseInput; | ||
``` |
25 changes: 25 additions & 0 deletions
25
docs/v0.2.3/Auth/login/anonymous-not-intended-for-production.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
--- | ||
title: "Anonymous (Not intended for Production)" | ||
slug: "anonymous-not-intended-for-production" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Mon Oct 16 2023 12:05:20 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:33:49 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
To simplify your onboarding with polyfire, we added an "anonymous" login method. | ||
|
||
It must first be activated in the dashboard in your project settings. | ||
|
||
**After that, logging in should be automatic.** | ||
|
||
You can also try to call it manually (after a logout for example) with: | ||
|
||
```js Javascript | ||
login({ provider: "anonymous" }); | ||
``` | ||
|
||
If you want to simulate multiple users, the login function also provides you with the ability to add an email to differentiate them like this: | ||
|
||
```js Javascript | ||
login({ provider: "anonymous", email: "[email protected]" }); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
--- | ||
title: "Custom Authentification System" | ||
slug: "custom-authentification-system" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Mon Oct 16 2023 11:41:24 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:33:49 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
If you are already using a custom authentification system and want to link Polyfire to your authentification system, you can use the "custom" provider. | ||
|
||
You will need to sign a Json Web Token using the RSA/RS256 algorithm and input your public key in the PEM format in the dashboard in the "Custom Auth Public Key" field of your project's settings. | ||
|
||
Your JWT must contains these fields: | ||
|
||
- `iss`: Your project alias | ||
- `aud`: must be:`polyfire_custom_auth_api` | ||
- `sub`: The id of the user you want to identify. It can be any string as long as it is unique to the user. | ||
|
||
For example. Assuming the public key is already added in the dashboard "Custom Auth Public Key" field, somewhere in server-side code: | ||
|
||
```js Javascript | ||
|
||
const token = jwt.sign( | ||
{ | ||
iss: projectAlias, | ||
aud: "polyfire_custom_auth_api", // Don't change this string | ||
sub: userID, | ||
}, | ||
privateKey, // Leaking this key would allow to connect as any user. Make sure it's never sent client-side. | ||
{ algorithm: "RS256" } | ||
); | ||
``` | ||
|
||
The generated token can then be used client-side in the login function like this: | ||
|
||
```js Javascript | ||
login({ provider: "custom", token: theTokenGeneratedBefore }) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
title: "Firebase" | ||
slug: "firebase" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Mon Oct 16 2023 11:40:36 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:33:49 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
## Add your Firebase Project ID to your project | ||
|
||
Before being able to use firebase as a login method you first need to link your Firebase project to your polyfire project. | ||
|
||
You can find your Firebase Project ID in your project settings in the firebase console <https://console.firebase.google.com/>. Choose your project, click on the gear icon in the top left corner and click on "Project Settings". Your Project ID will be displayed among other infos. | ||
|
||
To link it to your Polyfire project, go on <https://beta.polyfire.com/> and choose your project. When you are in the project detail page, click on the Edit button and add your Firebase Project ID before saving. | ||
|
||
## Setup the Firebase login | ||
|
||
If you didn't do it already, follow this tutorial to setup the login with firebase: <https://firebase.google.com/docs/auth/web/start> | ||
|
||
## Link your Firebase User Session to Polyfire | ||
|
||
You can set the provider to firebase and send a firebase token to the login function parameter. To get a firebase token, you can use the `getIdToken()` method of the firebase user object. | ||
|
||
For example: | ||
|
||
```js Javascript | ||
const userCredentials = await signInWithEmailAndPassword( | ||
auth, | ||
"[email protected]", | ||
"correct_horse_battery_staple" | ||
); | ||
|
||
const user = userCredentials.user; | ||
|
||
const firebaseToken = await user.getIdToken(); | ||
|
||
const polyfire = PolyfireClientBuilder({ project: "your_project_alias" }) | ||
await polyfire.auth.login({ provider: "firebase", token: firebaseToken }) | ||
|
||
// You can now use the Polyfire Client: | ||
const helloWorldHaiku = await polyfire.generate("Write me a hello world haiku"); | ||
|
||
console.log(helloWorldHaiku); | ||
``` | ||
|
||
> 📘 With the usePolyfire React Hook | ||
> | ||
> Using the usePolyfire React Hook it would work the same except that you would be importing the _auth_ module from usePolyfire instead of creating a client object like higher up. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
title: "OAuth Providers" | ||
slug: "login-with-providers" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Wed Sep 27 2023 07:17:47 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:41:44 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
For Polyfire to work client-side, **you need to setup unique user sessions**. That way, each user of your app will have a custom, rate-limited, API token and can use your app according to the restrictions you give them. | ||
|
||
To do that you can use our login functions, from the _auth_ module. | ||
|
||
```jsx | ||
import React from 'react'; | ||
import { usePolyfire } from 'polyfire-js/hooks'; | ||
|
||
function App() { | ||
const { auth } = usePolyfire(); | ||
const { login, status } = auth; | ||
|
||
if (status == 'loading') { | ||
return ( | ||
<div>Loading...</div> | ||
) | ||
} else if (status == 'authenticated') { | ||
return ( | ||
<div>We already logged in!</div> | ||
) | ||
} else if (status == 'unauthenticated') { | ||
return ( | ||
<button onClick={() => login("github")}>Login With GitHub</button> | ||
) | ||
} else { | ||
return <div /> | ||
} | ||
} | ||
|
||
export default App; | ||
``` | ||
|
||
# Linking pre-existing auth system | ||
|
||
If you have Firebase Auth setup. Pass in your JWT as shown [in that tutorial](doc:signin-firebase). If you want integrations to other auth providers:[message us on our Discord](https://www.polyfire.com/discord). | ||
|
||
You can also connect your own auth system [by doing a custom auth.](doc:custom-authentification-system) | ||
|
||
# Providers Available | ||
|
||
The sign in providers available are GitHub, Google, Microsoft (Azure) and Firebase (passing your Firebase JWT). | ||
|
||
[Reach out on Discord if you want more.](discord.polyfire.com) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
title: "logout" | ||
slug: "logout" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Wed Sep 27 2023 07:32:37 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:33:48 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
Ends user session and cleans cache. | ||
|
||
- Doesn't return anything. | ||
- Will require user to re-authenticate user to use API modules. (models, data, etc). | ||
|
||
```typescript | ||
export declare function logout(): Promise<void>; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
--- | ||
title: "Stripe Integration" | ||
slug: "react-stripe-subscriptions" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Mon Sep 11 2023 09:26:19 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Wed Nov 29 2023 15:37:38 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
# 1. Initialize the Stripe webhook | ||
|
||
- You first need a Polyfire project. You can [create one here](https://beta.polyfire.com/project/new). | ||
- Go to _Auth > Payments_ on your Polyfire dashboard. | ||
- Copy the webhook URL for one of the next steps. | ||
|
||
# 2. Configure User Rate Limits | ||
|
||
- **Free User Rate Limit** : | ||
Set a dollar threshold for free app usage under `Free User Rate Limit`. | ||
- **Premium User Rate Limit **: | ||
Assign a higher dollar limit for premium users in the `Premium User Rate Limit`. | ||
- **Developer Rate Limit Testing**: | ||
To test rate limits, toggle `Dev has rate limit?` to 'On' in development. | ||
Adjust or disable this in production. | ||
Now save your settings by clicking on the "Save" button. | ||
|
||
# 2. Add the webhook on the Stripe dashboard | ||
|
||
- Add the generated webhook [here on Stripe](https://dashboard.stripe.com/webhooks) . | ||
- Configure the webhook to be sent on all events (You can also select manually theses events: _customer.created, customer.updated, checkout.session.completed, customer.subscription.created, customer.subscription.updated and customer.subscription.deleted_) | ||
|
||
# 3. Create a payment link | ||
|
||
- Create a new Stripe payment link [here](https://dashboard.stripe.com/payment-links/create) on your Stripe dashboard. | ||
- In the product field, select Add new product, give it the name, image, description and price you want. Set the payment to Recurring and select Monthly in billing period. | ||
- In the After payment tab, choose Don't show confirmation page and set the address of your app. | ||
_NOTE: for localhost, use <http://127.0.0.1>, you will need this address instead of http\://localhost in your tests to stay connected after the payment._ | ||
- Create the link and copy it. | ||
|
||
# 4. Add the paywall to your app | ||
|
||
For this part, I am going to use the chat we made in this tutorial: [Making ChatGPT](doc:chatgpt-clone) | ||
|
||
We create a component that will be displayed instead of the chat if this user didn't pay yet. Don't forget to replace `<YOUR_STRIPE_PAYMENT_LINK>` by your payment link. | ||
|
||
Polyfire uses the userID as the identifier to know which user paid a subscription, this is why we use the client_reference_id query parameter. | ||
|
||
```jsx | ||
function Paywall({ userId }: { userId: string }) { | ||
return ( | ||
<div className="flex flex-col justify-center items-center h-full py-2"> | ||
<a className="cursor-pointer bg-black text-white ml-2 p-2 px-5 font-mono" href={`<YOUR_STRIPE_PAYMENT_LINK>?client_reference_id=${userId}`}> | ||
Access this application for only 420.69$/month | ||
</a> | ||
</div> | ||
); | ||
} | ||
|
||
``` | ||
|
||
We can then modify the App component to get the userId and add the paywall when the rate limit has been reached - which should be right away in this case since the rate limit is 0. | ||
|
||
```jsx | ||
function App() { | ||
const polyfire = usePolyfire(); | ||
|
||
const { login, status, user } = polyfire.auth; | ||
const { getAuthID, usage } = user; | ||
|
||
const { Chat } = polyfire.utils; | ||
|
||
|
||
const [chat, setChat] = useState<ChatType>(); | ||
const [paywall, setPaywall] = useState(false); | ||
const [userId, setUserId] = useState<string>(); | ||
const [messages, setMessages] = useState< | ||
{ is_user_message: boolean; content: string }[] | ||
>([]); | ||
|
||
useEffect(() => { | ||
if (status === "authenticated") { | ||
const updateUsage = async () => { | ||
const userId = await getAuthID(); | ||
setUserId(userId); | ||
|
||
const userUsage = await usage(); | ||
if (userUsage.rateLimit === undefined || userUsage.rateLimit === null) { | ||
setPaywall(false); | ||
} else { | ||
setPaywall(userUsage.rateLimit <= userUsage.usage); | ||
} | ||
|
||
setChat(new Chat()); | ||
}; | ||
|
||
updateUsage(); | ||
} | ||
}, [status]); | ||
|
||
if (status === "unauthenticated") { | ||
return ( | ||
<button onClick={() => login({ provider: "github" })}> | ||
Login with Github | ||
</button> | ||
); | ||
} | ||
|
||
if (chat && !paywall) { | ||
return ( | ||
<ChatBox | ||
messages={messages} | ||
onMessage={async (message: string) => { | ||
await chat.sendMessage(message); | ||
setMessages((await chat.getMessages()).reverse()); | ||
}} | ||
/> | ||
); | ||
} | ||
|
||
if (paywall && userId && status !== "loading") { | ||
return <Paywall userId={userId} />; | ||
} | ||
|
||
return <div>Loading...</div>; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
title: "user" | ||
slug: "user" | ||
excerpt: "" | ||
hidden: false | ||
createdAt: "Wed Sep 27 2023 07:39:48 GMT+0000 (Coordinated Universal Time)" | ||
updatedAt: "Fri Mar 01 2024 06:33:49 GMT+0000 (Coordinated Universal Time)" | ||
--- | ||
User object with Auth and Token IDs. | ||
|
||
- Give you access to a unique userID | ||
- Useful to mesure rateLimit and user's usage if you want to trigger a paywall / payment flow. | ||
|
||
```typescript | ||
export type UserClient = { | ||
usage: () => Promise<{ | ||
usage: number; | ||
rateLimit?: number; | ||
}>; | ||
getAuthID: () => Promise<string>; | ||
getToken: () => Promise<string>; | ||
}; | ||
``` |
Oops, something went wrong.