From c5f77db259696df55b5757cf191e371a788da386 Mon Sep 17 00:00:00 2001 From: pilcrowOnPaper Date: Sat, 6 Sep 2025 22:58:02 +0900 Subject: [PATCH] update to 0.4.0 --- pages/faroe-server/overview.md | 6 ++-- pages/faroe-server/quickstart-guide.md | 17 ++++++----- pages/faroe-server/setup.md | 42 ++++++++++++++++++-------- pages/index.md | 4 +-- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/pages/faroe-server/overview.md b/pages/faroe-server/overview.md index 9718972..fb48bac 100644 --- a/pages/faroe-server/overview.md +++ b/pages/faroe-server/overview.md @@ -16,9 +16,9 @@ Like any other auth server, client-side applications can use it to sign in, sign - User password reset - User deletion -One important distinction from existing servers is that Faroe does not store your users. Users are handled by a dedicated user server. Together, they complete a full auth system for your application. +One important distinction from existing servers is that Faroe does not directly store your users. Instead, you define a light abstraction over your app's database that allows Faroe to perform basic CRUD (create, read, update, delete) operations on your users. This gives you full control over your user data. You define the attributes your users have, how they're stored, and how they're managed. -Developers are responsible for building their own user server as part of their application. While this can be a bit of a hassle, it gives you full control over your user data. You define the attributes your users have, how they're stored, and how they're managed. The user server at its core is just a basic CRUD server so building it should be relatively straightforward. +Alternatively, you may create a separate user server (possibly in a different language) to handle queries to your app's database. In this setup, Faroe will make HTTP requests to your user server to interact with your user data. This also means that only ephemeral data is stored on the server. Even in a worst-case scenario such as complete data loss, your users would simply need to sign in again. There's no big overhead in maintaining the server. @@ -26,4 +26,4 @@ This architecture also removes the need of a complex storage layer in the server To get stated, see [Setup](/faroe-server/setup) page to learn how to use the package. Or, if you want to try out the server first, see the [Quick-start guide](/faroe-server/quickstart-guide) to run an prebuilt server locally. -Join our [Discord server](https://discord.gg/hEW2kwc8Jv) if you have any questions! \ No newline at end of file +Join our [Discord server](https://discord.gg/hEW2kwc8Jv) if you have any questions! diff --git a/pages/faroe-server/quickstart-guide.md b/pages/faroe-server/quickstart-guide.md index 41edad7..bc839af 100644 --- a/pages/faroe-server/quickstart-guide.md +++ b/pages/faroe-server/quickstart-guide.md @@ -8,13 +8,11 @@ Creating a Faroe server using the package may be a bigger commitment than some p This is a bare-bones Faroe implementation with everything stored in memory. It is only for local testing and **should not be used in production.** -To get started, clone the repository. +## With a user server -``` -git clone git@github.com:faroedev/local-server.git -``` +A user server is a dedicated server that handles user operations on your app's database. See the [user server overview](/user-server/overview) page for details. -Or, install a pre-built binary from [GitHub releases](https://github.com/faroedev/local-server/releases/latest). +Install a pre-built binary from [GitHub releases](https://github.com/faroedev/local-server/releases/latest). ``` https://github.com/faroedev/local-server/releases/latest/download/darwin-amd64.tgz @@ -25,9 +23,13 @@ https://github.com/faroedev/local-server/releases/latest/download/windows-386.tg https://github.com/faroedev/local-server/releases/latest/download/windows-amd64.tgz ``` -Start the server by passing the port number and your user server action invocation endpoint. +Or you can fork the project. + +``` +git clone git@github.com:faroedev/local-server.git +``` -See the [user server overview](/user-server/overview) page for details on user servers. No authentication is required for the action invocation endpoint. +Start the server by passing the port number and your user server action invocation endpoint. No authentication is required for the action invocation endpoint. ``` go run . 3001 "https://localhost:3000/user/invoke-action" @@ -37,6 +39,7 @@ go run . 3001 "https://localhost:3000/user/invoke-action" `/` is the action invocation endpoint (`http://localhost:3001` on port 3001). + ## What's missing for production? - **The user server action invocation endpoint is unprotected.** diff --git a/pages/faroe-server/setup.md b/pages/faroe-server/setup.md index 450934e..33cbd4b 100644 --- a/pages/faroe-server/setup.md +++ b/pages/faroe-server/setup.md @@ -64,6 +64,36 @@ type RateLimitStorageInterface interface { } ``` +## User store + +Create a user store that implements an [`UserStoreInterface`](https://pkg.go.dev/github.com/faroedev/faroe#UserStoreInterface). This allows Faroe to interact with your existing user data. + +```go +type UserStoreInterface interface { + CreateUser(emailAddress string, passwordHash []byte, passwordHashAlgorithmId string, passwordSalt []byte) (UserStruct, error) + GetUser(userId string) (UserStruct, error) + GetUserByEmailAddress(emailAddress string) (UserStruct, error) + UpdateUserEmailAddress(userId string, emailAddress string, userEmailAddressCounter int32) error + UpdateUserPasswordHash(userId string, passwordHash []byte, passwordHashAlgorithmId string, passwordSalt []byte, userPasswordHashCounter int32) error + IncrementUserSessionsCounter(userId string, userSessionsCounter int32) error + DeleteUser(userId string) error +} +``` + +Alternatively, you may create a separate [user server](/user-server/overview) to handle database operations for your users in a dedicated server. To connect to your user server, use [`NewUserServerClient()`](https://pkg.go.dev/github.com/faroedev/faroe#NewUserServerClient) to create [`UserServerStruct`](https://pkg.go.dev/github.com/faroedev/faroe#UserServerStruct), which implements `UserStoreInterface`. `NewUserServerClient()` takes an [`ActionInvocationEndpointClientInterface`](https://pkg.go.dev/github.com/faroedev/faroe#ActionInvocationEndpointClientInterface), which is used to send action invocation requests to the user server's action invocation endpoint + +```go +userStore := faroe.NewUserServerClient(actionInvocationEndpointClient) +``` + +```go +type ActionInvocationEndpointClientInterface interface { + SendActionInvocationEndpointRequest(body string) (string, error) +} +``` + +Because Faroe doesn't prescribe the authentication method used for action invocation endpoints, this is where you implement whatever authentication mechanism your user action endpoint uses. + ## User password hash algorithm The user password hash algorithm implements [`PasswordHashAlgorithmInterface`](https://pkg.go.dev/github.com/faroedev/faroe#PasswordHashAlgorithmInterface). The ID is a unique identifier for the algorithm. We recommend including the parameters alongside the algorithm name like `argon2id.65536.3.1.32`. @@ -84,18 +114,6 @@ The user password reset temporary password hash algorithm also implements [`Pass Temporary passwords used in user password resets are generated by the server. Because they are much stronger than user-defined passwords, you may use a weaker hashing algorithm than for user passwords. That said, you should still treat them as passwords and use hashing algorithms intended for passwords. We recommend Argon2id with 16MiB of memory, 3 iterations, and 1 degree of parallelism. -## User server action invocation endpoint client - -This client is used to send action invocation request to the user server's action invocation endpoint. It implements [`ActionInvocationEndpointClientInterface`](https://pkg.go.dev/github.com/faroedev/faroe#ActionInvocationEndpointClientInterface). - -Because Faroe doesn't prescribe the authentication method used for action invocation endpoints, this is where you implement whatever authentication mechanism your user action endpoint uses. - -```go -type ActionInvocationEndpointClientInterface interface { - SendActionInvocationEndpointRequest(body string) (string, error) -} -``` - ## Action error logger The `LogActionError()` method of [`ActionErrorLoggerInterface`](https://pkg.go.dev/github.com/faroedev/faroe#ActionErrorLoggerInterface) will be used to log all internal errors. diff --git a/pages/index.md b/pages/index.md index 375a0bc..b362c93 100644 --- a/pages/index.md +++ b/pages/index.md @@ -12,7 +12,7 @@ Some key features of the server: 1. Takes care of all the hard parts. Passwords, email address verification, sessions, rate limiting, password resets, and more. 2. Extends your existing user database instead of replacing it. Own and customize your user data. No more data synchronization between servers. -3. No direct connections to your database. Just basic HTTP requests. +3. No direct connections to your database. 4. Only ephemeral data is stored. Less things to manage and worry about. ```ts @@ -37,6 +37,7 @@ func main() { mainStorage, cache, rateLimitStorage, + userStore, logger, userPasswordHashAlgorithms, temporaryPasswordHashAlgorithm, @@ -44,7 +45,6 @@ func main() { faroe.RealClock, faroe.AllowAllEmailAddresses, emailSender, - userActionInvocationEndpointClient, sessionConfig, ) }