### Start Test Server Source: https://github.com/supertokens/supertokens-golang/blob/master/CONTRIBUTING.md Starts the test server for the SuperTokens Go project. Ensure you are in the `test-server` directory. ```bash go run . ``` -------------------------------- ### Run go-zero Server Source: https://github.com/supertokens/supertokens-golang/blob/master/examples/with-go-zero/README.md Use this command to start the go-zero server integrated with SuperTokens. Ensure you have the main.go file in your current directory. ```bash go run main.go ``` -------------------------------- ### Install and Build Backend SDK Testing Source: https://github.com/supertokens/supertokens-golang/blob/master/CONTRIBUTING.md Installs dependencies and builds the `backend-sdk-testing` project. Requires Node.js version >= 16.20.0 and < 17.0.0. ```bash npm install && npm run build-pretty ``` -------------------------------- ### Run Twirp Server with SuperTokens Middleware Source: https://github.com/supertokens/supertokens-golang/blob/master/examples/with-twirp/README.md This command starts the Go server that integrates Twirp with SuperTokens. Ensure you have Go installed and the project dependencies are set up. ```bash go run cmd/server/main.go ``` -------------------------------- ### Example Server Output Source: https://github.com/supertokens/supertokens-golang/blob/master/examples/with-twirp/cmd/server/README.md When the server runs, it logs statsd messages indicating request metrics. Observe these logs to understand the server's internal metrics reporting. ```text -> % ./server incr twirp.total.requests: 1 @ 1.000000 incr twirp.MakeHat.requests: 1 @ 1.000000 incr twirp.total.responses: 1 @ 1.000000 incr twirp.MakeHat.responses: 1 @ 1.000000 incr twirp.status_codes.total.200: 1 @ 1.000000 incr twirp.status_codes.MakeHat.200: 1 @ 1.000000 time twirp.all_methods.response: 370.695µs @ 1.000000 time twirp.MakeHat.response: 370.695µs @ 1.000000 time twirp.status_codes.all_methods.200: 370.695µs @ 1.000000 time twirp.status_codes.MakeHat.200: 370.695µs @ 1.000000 ``` -------------------------------- ### Get User Permissions in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Retrieve all permissions for a user by first fetching their roles using `GetRolesForUser` and then their permissions using `GetPermissionsForRole`. ```go import ( "github.com/supertokens/supertokens-golang/recipe/userroles" ) func getUserPermissions(tenantId, userID string) ([]string, error) { rolesResp, err := userroles.GetRolesForUser(tenantId, userID) if err != nil { return nil, err } var allPerms []string for _, role := range rolesResp.OK.Roles { permResp, err := userroles.GetPermissionsForRole(role) if err != nil { return nil, err } allPerms = append(allPerms, permResp.OK.Permissions...) } return allPerms, nil } ``` -------------------------------- ### Get User Metadata in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Retrieve a user's metadata using `GetUserMetadata`. The returned map contains all stored metadata, which can be accessed by key. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/usermetadata" ) func getUserProfile(userID string) (map[string]interface{}, error) { metadata, err := usermetadata.GetUserMetadata(userID) if err != nil { return nil, err } // metadata["displayName"], metadata["preferences"], etc. fmt.Printf("User display name: %v\n", metadata["displayName"]) return metadata, nil } ``` -------------------------------- ### API Call Utilities for Testing Source: https://github.com/supertokens/supertokens-golang/blob/master/test/frontendIntegration/static/index.html These asynchronous functions use Axios to make GET requests to specific SuperTokens backend endpoints for testing purposes. They are useful for verifying refresh counts, session calls, and package versions. ```javascript import umdAssert from 'https://cdn.skypack.dev/umd-assert'; window.assert = umdAssert; if (axios.default) { axios = axios.default; } async function getNumberOfTimesRefreshCalled(BASE_URL = "http://localhost.org:8080") { let instance = axios.create(); let response = await instance.get(BASE_URL + "/refreshCalledTime"); return response.data; }; async function getNumberOfTimesRefreshAttempted(BASE_URL = "http://localhost.org:8080") { let instance = axios.create(); let response = await instance.get(BASE_URL + "/refreshAttemptedTime"); return response.data; }; async function getNumberOfTimesGetSessionCalled(BASE_URL = "http://localhost.org:8080") { let instance = axios.create(); let response = await instance.get(BASE_URL + "/getSessionCalledTime"); return response.data; }; async function getPackageVersion(BASE_URL = "http://localhost.org:8080") { let instance = axios.create(); let response = await instance.get(BASE_URL + "/getPackageVersion"); return response.data; }; ``` -------------------------------- ### Initialize SuperTokens SDK in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Bootstraps the SuperTokens SDK with application info, core connection, and enabled recipes. Must be called before any other SDK function. Ensure the SuperTokens core is running and accessible via the provided ConnectionURI. ```go package main import ( "net/http" "github.com/supertokens/supertokens-golang/recipe/emailpassword" "github.com/supertokens/supertokens-golang/recipe/emailverification" "github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/dashboard" "github.com/supertokens/supertokens-golang/supertokens" ) func main() { err := supertokens.Init(supertokens.TypeInput{ Supertokens: &supertokens.ConnectionInfo{ ConnectionURI: "http://localhost:3567", // self-hosted core APIKey: "your-api-key", // if core has an API key set }, AppInfo: supertokens.AppInfo{ AppName: "My App", APIDomain: "http://localhost:8080", WebsiteDomain: "http://localhost:3000", APIBasePath: strPtr("/auth"), // optional, default is "/auth" }, RecipeList: []supertokens.Recipe{ emailverification.Init(evmodels.TypeInput{ Mode: evmodels.ModeRequired, }), emailpassword.Init(nil), session.Init(nil), dashboard.Init(nil), }, }) if err != nil { panic(err) } http.ListenAndServe(":8080", supertokens.Middleware(http.DefaultServeMux)) } func strPtr(s string) *string { return &s } ``` -------------------------------- ### Run Backend SDK Testing Source: https://github.com/supertokens/supertokens-golang/blob/master/CONTRIBUTING.md Runs all tests for the `backend-sdk-testing` project. Ensure `INSTALL_PATH` is set correctly. ```bash INSTALL_PATH=../supertokens-root npm test ``` -------------------------------- ### Email+Password User Sign-Up Source: https://context7.com/supertokens/supertokens-golang/llms.txt Registers a new user with email and password. Handles cases where the email is already registered. Requires a 'public' tenant ID. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/emailpassword" ) func registerUser(email, password string) error { result, err := emailpassword.SignUp("public", email, password) if err != nil { return err } if result.EmailAlreadyExistsError != nil { return fmt.Errorf("email already registered") } fmt.Printf("New user created: %s\n", result.OK.User.ID) return nil } ``` -------------------------------- ### Email+Password User Sign-In Source: https://context7.com/supertokens/supertokens-golang/llms.txt Authenticates an existing user using email and password credentials. Returns an error for invalid credentials. Requires a 'public' tenant ID. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/emailpassword" ) func authenticateUser(email, password string) (string, error) { result, err := emailpassword.SignIn("public", email, password) if err != nil { return "", err } if result.WrongCredentialsError != nil { return "", fmt.Errorf("invalid credentials") } return result.OK.User.ID, nil } ``` -------------------------------- ### supertokens.Init — Initialize the SDK Source: https://context7.com/supertokens/supertokens-golang/llms.txt Bootstraps the SuperTokens SDK with application info, a connection to the core service, and a list of enabled recipe modules. Must be called before any other SDK function. ```APIDOC ## supertokens.Init — Initialize the SDK ### Description Bootstraps the SuperTokens SDK with application info, a connection to the core service, and a list of enabled recipe modules. Must be called before any other SDK function. ### Usage ```go package main import ( "net/http" "github.com/supertokens/supertokens-golang/recipe/emailpassword" "github.com/supertokens/supertokens-golang/recipe/emailverification" "github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/dashboard" "github.com/supertokens/supertokens-golang/supertokens" ) func main() { err := supertokens.Init(supertokens.TypeInput{ Supertokens: &supertokens.ConnectionInfo{ ConnectionURI: "http://localhost:3567", // self-hosted core APIKey: "your-api-key", // if core has an API key set }, AppInfo: supertokens.AppInfo{ AppName: "My App", APIDomain: "http://localhost:8080", WebsiteDomain: "http://localhost:3000", APIBasePath: strPtr("/auth"), // optional, default is "/auth" }, RecipeList: []supertokens.Recipe{ emailverification.Init(evmodels.TypeInput{ Mode: evmodels.ModeRequired, }), emailpassword.Init(nil), session.Init(nil), dashboard.Init(nil), }, }) if err != nil { panic(err) } http.ListenAndServe(":8080", supertokens.Middleware(http.DefaultServeMux)) } func strPtr(s string) *string { return &s } ``` ``` -------------------------------- ### List Users with Pagination in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Fetch users in descending order of creation time using `GetUsersNewestFirst`. Implement a loop to handle pagination using `NextPaginationToken`. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/supertokens" ) func listUsers(tenantId string) error { limit := 10 var paginationToken *string for { result, err := supertokens.GetUsersNewestFirst(tenantId, paginationToken, &limit, nil, nil) if err != nil { return err } for _, u := range result.Users { fmt.Printf("User ID: %s, Recipe: %s\n", u.User["id"], u.RecipeId) } if result.NextPaginationToken == nil { break } paginationToken = result.NextPaginationToken } return nil } ``` -------------------------------- ### List All Tenants in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Retrieve a list of all tenants using `ListAllTenants`. Iterate through the response to access individual tenant details. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/multitenancy" ) func listTenants() error { result, err := multitenancy.ListAllTenants() if err != nil { return err } for _, t := range result.OK.Tenants { fmt.Printf("Tenant: %s\n", t.TenantId) } return nil } ``` -------------------------------- ### Provision Tenant Configuration in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use `CreateOrUpdateTenant` to provision a new tenant or update an existing one. Configure features like email password and passwordless authentication. ```go import ( "github.com/supertokens/supertokens-golang/recipe/multitenancy" "github.com/supertokens/supertokens-golang/recipe/multitenancy/multitenancymodels" ) func provisionTenant(tenantId string) error { emailEnabled := true passwordlessEnabled := true result, err := multitenancy.CreateOrUpdateTenant(tenantId, multitenancymodels.TenantConfig{ EmailPasswordEnabled: &emailEnabled, PasswordlessEnabled: &passwordlessEnabled, }) if err != nil { return err } _ = result.OK.CreatedNew return nil } ``` -------------------------------- ### Create Roles and Assign Permissions in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use `CreateNewRoleOrAddPermissions` to define roles and their associated permissions. Ensure roles are created before assigning them to users. ```go import ( "github.com/supertokens/supertokens-golang/recipe/userroles" ) func setupRoles() error { // Create or extend a role with permissions _, err := userroles.CreateNewRoleOrAddPermissions("admin", []string{ "read:users", "write:users", "delete:users", }) if err != nil { return err } _, err = userroles.CreateNewRoleOrAddPermissions("viewer", []string{"read:users"}) return err } ``` -------------------------------- ### Run All Go Tests Source: https://github.com/supertokens/supertokens-golang/blob/master/CONTRIBUTING.md Execute all tests for the SuperTokens Go project. Use `count=1` to ensure tests are not cached. ```bash INSTALL_DIR=../supertokens-root go test ./... -p 1 -v count=1 ``` -------------------------------- ### Create and Verify Email Verification Tokens in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use `CreateEmailVerificationToken` to generate a token for email verification and `VerifyEmailUsingToken` to validate it. Handles cases where the email is already verified or the token is invalid. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/emailverification" ) func sendVerificationEmail(tenantId, userID string) error { // nil email auto-fetches the email from the user's recipe resp, err := emailverification.CreateEmailVerificationToken(tenantId, userID, nil) if err != nil { return err } if resp.EmailAlreadyVerifiedError != nil { fmt.Println("Email is already verified") return nil } verifyLink := fmt.Sprintf("https://myapp.com/verify-email?token=%s&tenantId=%s", resp.OK.Token, tenantId) fmt.Println("Verification link:", verifyLink) return nil } func verifyToken(tenantId, token string) error { result, err := emailverification.VerifyEmailUsingToken(tenantId, token) if err != nil { return err } if result.EmailVerificationInvalidTokenError != nil { return fmt.Errorf("invalid or expired token") } fmt.Printf("Email verified for user: %s\n", result.OK.User.ID) return nil } func checkVerified(userID string) (bool, error) { return emailverification.IsEmailVerified(userID, nil) } ``` -------------------------------- ### emailpassword.SignUp / SignIn Source: https://context7.com/supertokens/supertokens-golang/llms.txt Handles user authentication using email and password. The SignUp function registers a new user, while the SignIn function authenticates an existing user. ```APIDOC ## emailpassword.SignUp / SignIn — Email+Password Authentication Registers a new user or authenticates an existing one with email and password credentials. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/emailpassword" ) func registerUser(email, password string) error { result, err := emailpassword.SignUp("public", email, password) if err != nil { return err } if result.EmailAlreadyExistsError != nil { return fmt.Errorf("email already registered") } fmt.Printf("New user created: %s\n", result.OK.User.ID) return nil } func authenticateUser(email, password string) (string, error) { result, err := emailpassword.SignIn("public", email, password) if err != nil { return "", err } if result.WrongCredentialsError != nil { return "", fmt.Errorf("invalid credentials") } return result.OK.User.ID, nil } ``` ``` -------------------------------- ### Passwordless OTP Login with Email in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Utilize `CreateCodeWithEmail` to send an OTP or magic link to a user's email. `ConsumeCodeWithUserInputCode` is then used to verify the provided code and authenticate the user. Handles incorrect codes, expired codes, and restart requirements. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/passwordless" ) func sendOTPToEmail(tenantId, email string) (deviceID, preAuthSessionID string, err error) { result, err := passwordless.CreateCodeWithEmail(tenantId, email, nil) if err != nil { return "", "", err } // result.OK.DeviceID and PreAuthSessionID are needed for code consumption return result.OK.DeviceID, result.OK.PreAuthSessionID, nil } func verifyOTP(tenantId, deviceID, userInputCode, preAuthSessionID string) (string, error) { result, err := passwordless.ConsumeCodeWithUserInputCode( tenantId, deviceID, userInputCode, preAuthSessionID, ) if err != nil { return "", err } if result.IncorrectUserInputCodeError != nil { remaining := result.IncorrectUserInputCodeError.MaximumCodeInputAttempts - result.IncorrectUserInputCodeError.FailedCodeInputAttemptCount return "", fmt.Errorf("wrong OTP, %d attempts remaining", remaining) } if result.ExpiredUserInputCodeError != nil { return "", fmt.Errorf("OTP expired") } if result.RestartFlowError != nil { return "", fmt.Errorf("too many failed attempts, restart required") } fmt.Printf("Logged in user: %s (new=%v)\n", result.OK.User.ID, result.OK.CreatedNewUser) return result.OK.User.ID, nil } func sendMagicLink(tenantId, email string) (string, error) { return passwordless.CreateMagicLinkByEmail(tenantId, email) } ``` -------------------------------- ### Associate User to Tenant in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use `AssociateUserToTenant` to link a user to a specific tenant. Handle `UnknownUserIdError` and `UserAlreadyAssociatedError` for robust error management. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/multitenancy" ) func addUserToTenant(tenantId, userId string) error { result, err := multitenancy.AssociateUserToTenant(tenantId, userId) if err != nil { return err } if result.UnknownUserIdError != nil { return fmt.Errorf("user not found") } if result.UserAlreadyAssociatedError != nil { return fmt.Errorf("user already in tenant") } return nil } ``` -------------------------------- ### Multi-Tenant Management Source: https://context7.com/supertokens/supertokens-golang/llms.txt Functions for creating and updating tenants, and associating users with specific tenants. ```APIDOC ## multitenancy.CreateOrUpdateTenant / AssociateUserToTenant — Multi-Tenant Management Creates or configures tenants and manages user associations across isolated tenant spaces. ### Functions * **CreateOrUpdateTenant(tenantId string, config multitenancymodels.TenantConfig) (CreateOrUpdateTenantOK, error)**: Creates a new tenant or updates an existing one with the provided configuration. * **AssociateUserToTenant(tenantId string, userId string) (AssociateUserToTenantOK | UnknownUserIdError | UserAlreadyAssociatedError, error)**: Associates a user with a specified tenant. * **ListAllTenants() (ListAllTenantsOK, error)**: Retrieves a list of all tenants configured in the system. ### Example Usage ```go import ( "github.com/supertokens/supertokens-golang/recipe/multitenancy" "github.com/supertokens/supertokens-golang/recipe/multitenancy/multitenancymodels" ) func provisionTenant(tenantId string) error { emailEnabled := true passwordlessEnabled := true result, err := multitenancy.CreateOrUpdateTenant(tenantId, multitenancymodels.TenantConfig{ EmailPasswordEnabled: &emailEnabled, PasswordlessEnabled: &passwordlessEnabled, }) if err != nil { return err } _ = result.OK.CreatedNew return nil } func addUserToTenant(tenantId, userId string) error { result, err := multitenancy.AssociateUserToTenant(tenantId, userId) if err != nil { return err } if result.UnknownUserIdError != nil { return fmt.Errorf("user not found") } if result.UserAlreadyAssociatedError != nil { return fmt.Errorf("user already in tenant") } return nil } func listTenants() error { result, err := multitenancy.ListAllTenants() if err != nil { return err } for _, t := range result.OK.Tenants { fmt.Printf("Tenant: %s\n", t.TenantId) } return nil } ``` ``` -------------------------------- ### Initiate Password Reset Source: https://context7.com/supertokens/supertokens-golang/llms.txt Generates a password reset token for a given user ID and tenant ID. The generated token should be included in a password reset link sent to the user. Handles cases where the user ID is not found. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/emailpassword" ) func initiatePasswordReset(tenantId, userID string) (string, error) { result, err := emailpassword.CreateResetPasswordToken(tenantId, userID) if err != nil { return "", err } if result.UnknownUserIdError != nil { return "", fmt.Errorf("user not found") } // result.OK.Token is the token to include in the reset link resetLink := fmt.Sprintf("https://myapp.com/reset-password?token=%s&tenantId=%s", result.OK.Token, tenantId) fmt.Println("Send to user:", resetLink) return result.OK.Token, nil } ``` -------------------------------- ### Create New Session After Authentication Source: https://context7.com/supertokens/supertokens-golang/llms.txt Call this function after a user successfully authenticates to create a new session. It sets access and refresh token cookies or headers. ```go import ( "net/http" "github.com/supertokens/supertokens-golang/recipe/emailpassword" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/supertokens" ) func loginHandler(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") password := r.FormValue("password") result, err := emailpassword.SignIn("public", email, password) if err != nil { http.Error(w, err.Error(), 500) return } if result.WrongCredentialsError != nil { http.Error(w, "Invalid credentials", 401) return } // Create a new session for the authenticated user _, err = session.CreateNewSession( r, w, "public", // tenantId result.OK.User.ID, // userId map[string]interface{}{ "role": "admin", }, // accessTokenPayload (embedded in JWT) map[string]interface{}{ "signupDate": "2024-01-01", }, // sessionDataInDatabase (server-side only) ) if err != nil { http.Error(w, err.Error(), 500) return } w.WriteHeader(200) w.Write([]byte("Login successful")) } ``` -------------------------------- ### Create Session Without Request/Response in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use this function in serverless environments, WebSockets, or background workers where HTTP request/response objects are unavailable. It creates a new session for a given user and tenant. ```go import ( "github.com/supertokens/supertokens-golang/recipe/session" ) func createSessionForWorker(tenantId, userID string) (accessToken string, err error) { disableAntiCSRF := true sess, err := session.CreateNewSessionWithoutRequestResponse( tenantId, userID, map[string]interface{}{"source": "worker"}, nil, // no server-side session data &disableAntiCSRF, ) if err != nil { return "", err } tokens := sess.GetAllSessionTokensDangerously() return tokens.AccessToken, nil } ``` -------------------------------- ### Assign Role to User in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use `AddRoleToUser` to assign a pre-defined role to a user within a specific tenant. Check for `UnknownRoleError` if the role does not exist. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/userroles" ) func assignRole(tenantId, userID, role string) error { result, err := userroles.AddRoleToUser(tenantId, userID, role) if err != nil { return err } if result.UnknownRoleError != nil { return fmt.Errorf("role %q does not exist", role) } return nil } ``` -------------------------------- ### User Roles Management Source: https://context7.com/supertokens/supertokens-golang/llms.txt Functions for creating roles, adding permissions to roles, and assigning roles to users. Also includes fetching user permissions. ```APIDOC ## userroles.CreateNewRoleOrAddPermissions / AddRoleToUser — Role-Based Access Control Creates roles with granular permissions and assigns them to users for RBAC enforcement. ### Functions * **CreateNewRoleOrAddPermissions(roleName string, permissions []string) (CreateNewRoleOrAddPermissionsOK, error)**: Creates a new role or adds permissions to an existing role. * **AddRoleToUser(tenantId string, userId string, role string) (AddRoleToUserOK | UnknownRoleError | UserAlreadyHasRoleError, error)**: Assigns a specified role to a user within a tenant. * **GetRolesForUser(tenantId string, userId string) (GetRolesForUserOK | UnknownUserError, error)**: Retrieves all roles assigned to a user in a specific tenant. * **GetPermissionsForRole(role string) (GetPermissionsForRoleOK | UnknownRoleError, error)**: Fetches all permissions associated with a given role. ### Example Usage ```go import ( "github.com/supertokens/supertokens-golang/recipe/userroles" ) func setupRoles() error { // Create or extend a role with permissions _, err := userroles.CreateNewRoleOrAddPermissions("admin", []string{ "read:users", "write:users", "delete:users", }) if err != nil { return err } _, err = userroles.CreateNewRoleOrAddPermissions("viewer", []string{"read:users"}) return err } func assignRole(tenantId, userID, role string) error { result, err := userroles.AddRoleToUser(tenantId, userID, role) if err != nil { return err } if result.UnknownRoleError != nil { return fmt.Errorf("role %q does not exist", role) } return nil } func getUserPermissions(tenantId, userID string) ([]string, error) { rolesResp, err := userroles.GetRolesForUser(tenantId, userID) if err != nil { return nil, err } var allPerms []string for _, role := range rolesResp.OK.Roles { permResp, err := userroles.GetPermissionsForRole(role) if err != nil { return nil, err } allPerms = append(allPerms, permResp.OK.Permissions...) } return allPerms, nil } ``` ``` -------------------------------- ### Load Angular Application Source: https://github.com/supertokens/supertokens-golang/blob/master/test/frontendIntegration/static/index.html Dynamically loads an Angular application by appending necessary script tags to the document body. Ensures the application is loaded only once. ```javascript function loadAngular() { if (window.angularHttpClient !== undefined) { return; } document.body.appendChild(document.createElement("app-root")); const scripts = [ "/angular/runtime.js", "/angular/polyfills.js", "/angular/vendor.js", "/angular/main.js", ]; const loadPromises = []; for (const src of scripts) { const tag = document.createElement("script"); tag.src = src; tag.type = "module"; loadPromises.push(new Promise(res => tag.onload = res)); document.body.appendChild(tag); } return Promise.all(loadPromises); } ``` -------------------------------- ### User Management Source: https://context7.com/supertokens/supertokens-golang/llms.txt Functions for listing users and deleting users across all recipes. ```APIDOC ## supertokens.GetUsersNewestFirst / DeleteUser — User Management Lists all registered users with pagination and deletes a user across all recipes. ### Functions * **GetUsersNewestFirst(tenantId string, paginationToken *string, limit *int, sortBy *string, filter *string) (GetUsersNewestFirstOK, error)**: Retrieves a list of users, sorted newest first, with optional pagination and filtering. * **DeleteUser(userId string) (DeleteUserOK, error)**: Deletes a user from all recipe stores and removes all their sessions. ### Example Usage ```go import ( "fmt" "github.com/supertokens/supertokens-golang/supertokens" ) func listUsers(tenantId string) error { limit := 10 var paginationToken *string for { result, err := supertokens.GetUsersNewestFirst(tenantId, paginationToken, &limit, nil, nil) if err != nil { return err } for _, u := range result.Users { fmt.Printf("User ID: %s, Recipe: %s\n", u.User["id"], u.RecipeId) } if result.NextPaginationToken == nil { break } paginationToken = result.NextPaginationToken } return nil } func removeUser(userID string) error { return supertokens.DeleteUser(userID) // Deletes the user from all recipe stores and removes all sessions } ``` ``` -------------------------------- ### Manually Create or Update Third-Party User in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use `ManuallyCreateOrUpdateUser` to manage users from third-party OAuth providers like Google. This is useful for custom OAuth flows or migrations. It returns the user ID and indicates if a new user was created. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/thirdparty" ) func upsertGoogleUser(tenantId, googleUserId, email string) (string, error) { result, err := thirdparty.ManuallyCreateOrUpdateUser( tenantId, "google", // thirdPartyId googleUserId, // thirdPartyUserId (Google's sub claim) email, ) if err != nil { return "", err } if result.EmailChangeNotAllowedError != nil { return "", fmt.Errorf("email change not allowed: %s", result.EmailChangeNotAllowedError.Reason) } fmt.Printf("User %s (new=%v)\n", result.OK.User.ID, result.OK.CreatedNewUser) return result.OK.User.ID, nil } ``` -------------------------------- ### Delete User in Go Source: https://context7.com/supertokens/supertokens-golang/llms.txt Remove a user and all their associated data across all recipes using `DeleteUser`. This action is irreversible. ```go import ( "github.com/supertokens/supertokens-golang/supertokens" ) func removeUser(userID string) error { return supertokens.DeleteUser(userID) // Deletes the user from all recipe stores and removes all sessions } ``` -------------------------------- ### Assertion Helper Functions Source: https://github.com/supertokens/supertokens-golang/blob/master/test/frontendIntegration/static/index.html Provides simple assertion functions for testing equality and inequality. Throws an error if the condition is not met. ```javascript function assertEqual(a, b) { if (a !== b) { throw new Error(`assert failed ${a} === ${b}`); } } function assertNotEqual(a, b) { if (a === b) { throw new Error(`assert failed ${a} !== ${b}`); } } ``` -------------------------------- ### Protect API Route with Session Verification Source: https://context7.com/supertokens/supertokens-golang/llms.txt Use this middleware wrapper to validate sessions for incoming requests. It returns a 401/403 if the session is missing or invalid. Configure options like `SessionRequired` and `CheckDatabase` for custom behavior. ```go import ( "encoding/json" "net/http" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/recipe/session/sessmodels" ) func registerRoutes(mux *http.ServeMux) { // Basic session check (session required) mux.HandleFunc("/api/profile", session.VerifySession(nil, profileHandler)) // Optional session (session not required) checkDatabase := false sessionNotRequired := false mux.HandleFunc("/api/public", session.VerifySession(&sessmodels.VerifySessionOptions{ SessionRequired: &sessionNotRequired, CheckDatabase: &checkDatabase, }, publicHandler)) } func profileHandler(w http.ResponseWriter, r *http.Request) { sess := session.GetSessionFromRequestContext(r.Context()) // sess is guaranteed non-nil here payload := sess.GetAccessTokenPayload() userID := sess.GetUserID() tenantID := sess.GetTenantId() json.NewEncoder(w).Encode(map[string]interface{}{ "userId": userID, "tenantId": tenantID, "payload": payload, }) } func publicHandler(w http.ResponseWriter, r *http.Request) { sess := session.GetSessionFromRequestContext(r.Context()) if sess == nil { w.Write([]byte("anonymous")) return } w.Write([]byte("logged in as " + sess.GetUserID())) } ``` -------------------------------- ### Apply SuperTokens Session Middleware to Twirp Handler Source: https://github.com/supertokens/supertokens-golang/blob/master/examples/with-twirp/README.md This Go code snippet shows how to apply SuperTokens session verification middleware to a Twirp RPC handler. It uses `verifySession` in optional mode, allowing requests without a session to proceed while still making session data available if a session exists. ```go CORS(supertokens.Middleware(verifySession(twirpServer))) ``` -------------------------------- ### emailpassword.CreateResetPasswordToken / ResetPasswordUsingToken Source: https://context7.com/supertokens/supertokens-golang/llms.txt Manages the password reset process. CreateResetPasswordToken generates a token for a user, and ResetPasswordUsingToken consumes this token to set a new password. ```APIDOC ## emailpassword.CreateResetPasswordToken / ResetPasswordUsingToken — Password Reset Generates a password reset token for a user and consumes it to set a new password. ```go import ( "fmt" "github.com/supertokens/supertokens-golang/recipe/emailpassword" ) func initiatePasswordReset(tenantId, userID string) (string, error) { result, err := emailpassword.CreateResetPasswordToken(tenantId, userID) if err != nil { return "", err } if result.UnknownUserIdError != nil { return "", fmt.Errorf("user not found") } // result.OK.Token is the token to include in the reset link resetLink := fmt.Sprintf("https://myapp.com/reset-password?token=%s&tenantId=%s", result.OK.Token, tenantId) fmt.Println("Send to user:", resetLink) return result.OK.Token, nil } func completePasswordReset(tenantId, token, newPassword string) error { result, err := emailpassword.ResetPasswordUsingToken(tenantId, token, newPassword) if err != nil { return err } if result.ResetPasswordInvalidTokenError != nil { return fmt.Errorf("invalid or expired token") } // result.OK.UserID contains the user who reset their password fmt.Printf("Password reset for user: %s\n", result.OK.UserId) return nil } ``` ``` -------------------------------- ### Passwordless OTP and Magic Link Functions Source: https://context7.com/supertokens/supertokens-golang/llms.txt Enables passwordless authentication by sending One-Time Passwords (OTPs) or magic links to a user's email or phone, and provides functions to consume these codes for authentication. ```APIDOC ## passwordless.CreateCodeWithEmail / ConsumeCodeWithUserInputCode — Passwordless OTP Login Sends an OTP (or magic link) to a user's email or phone and consumes the code to authenticate. ### `CreateCodeWithEmail(tenantId string, email string, phoneNumber *string)` Creates an OTP or magic link to be sent to the user's email or phone number. - **tenantId** (string) - The ID of the tenant. - **email** (string) - The user's email address. - **phoneNumber** (*string) - Optional. The user's phone number. If provided, the code is sent via SMS. ### `ConsumeCodeWithUserInputCode(tenantId string, deviceID string, userInputCode string, preAuthSessionID string)` Consumes the OTP or magic link code provided by the user. - **tenantId** (string) - The ID of the tenant. - **deviceID** (string) - The device ID obtained from `CreateCodeWithEmail`. - **userInputCode** (string) - The OTP or magic link code entered by the user. - **preAuthSessionID** (string) - The pre-authentication session ID obtained from `CreateCodeWithEmail`. ### `CreateMagicLinkByEmail(tenantId string, email string)` Creates a magic link for email-based passwordless login. - **tenantId** (string) - The ID of the tenant. - **email** (string) - The user's email address. ### Request Example (Send OTP to Email) ```go deviceID, preAuthSessionID, err := passwordless.CreateCodeWithEmail(tenantId, email, nil) if err != nil { // handle error } // Use deviceID and preAuthSessionID to verify the code later ``` ### Request Example (Verify OTP) ```go result, err := passwordless.ConsumeCodeWithUserInputCode( tenantId, deviceID, userInputCode, preAuthSessionID, ) if err != nil { // handle error } if result.IncorrectUserInputCodeError != nil { // handle incorrect code, check remaining attempts } if result.ExpiredUserInputCodeError != nil { // handle expired code } if result.RestartFlowError != nil { // handle too many attempts, restart flow } // Access logged-in user ID: result.OK.User.ID // Check if new user was created: result.OK.CreatedNewUser ``` ### Request Example (Send Magic Link) ```go magicLink, err := passwordless.CreateMagicLinkByEmail(tenantId, email) if err != nil { // handle error } // Send magicLink to the user ``` ### Response (Create Code/Magic Link) - **OK** struct - Contains `DeviceID` and `PreAuthSessionID` for OTP, or the magic link URL. ### Response (Consume Code) - **OK** struct - Contains user details and a flag indicating if a new user was created. - **IncorrectUserInputCodeError** struct - If the provided code is incorrect. Includes attempt counts. - **ExpiredUserInputCodeError** struct - If the provided code has expired. - **RestartFlowError** struct - If too many failed attempts have occurred, requiring a flow restart. ``` -------------------------------- ### Email Verification Functions Source: https://context7.com/supertokens/supertokens-golang/llms.txt Provides functions to create an email verification token for a user and to verify a token. It also includes a utility to check if an email is already verified. ```APIDOC ## emailverification.CreateEmailVerificationToken / VerifyEmailUsingToken — Email Verification Creates a verification token for a user's email address and verifies the token when the user clicks the link. ### `CreateEmailVerificationToken(tenantId string, userID string, email *string)` Creates an email verification token for the specified user. - **tenantId** (string) - The ID of the tenant. - **userID** (string) - The ID of the user. - **email** (*string) - Optional. The email address of the user. If nil, the email is fetched from the user's recipe. ### `VerifyEmailUsingToken(tenantId string, token string)` Verifies the provided email verification token. - **tenantId** (string) - The ID of the tenant. - **token** (string) - The email verification token. ### `IsEmailVerified(userID string, email *string)` Checks if the user's email is verified. - **userID** (string) - The ID of the user. - **email** (*string) - Optional. The email address to check. If nil, the primary email is used. ### Request Example (Create Token) ```go // nil email auto-fetches the email from the user's recipe resp, err := emailverification.CreateEmailVerificationToken(tenantId, userID, nil) if err != nil { // handle error } if resp.EmailAlreadyVerifiedError != nil { // handle email already verified } verifyLink := fmt.Sprintf("https://myapp.com/verify-email?token=%s&tenantId=%s", resp.OK.Token, tenantId) ``` ### Request Example (Verify Token) ```go result, err := emailverification.VerifyEmailUsingToken(tenantId, token) if err != nil { // handle error } if result.EmailVerificationInvalidTokenError != nil { // handle invalid token } // Access verified user ID: result.OK.User.ID ``` ### Response (Create Token) - **OK** struct - Contains the token and user details if successful. - **EmailAlreadyVerifiedError** struct - If the email is already verified. ### Response (Verify Token) - **OK** struct - Contains the verified user details if successful. - **EmailVerificationInvalidTokenError** struct - If the token is invalid or expired. ``` -------------------------------- ### session.CreateNewSession Source: https://context7.com/supertokens/supertokens-golang/llms.txt Creates a new session for a user after successful authentication. This function sets the necessary access and refresh token cookies or headers. It's typically called once a user has logged in or signed up. ```APIDOC ## session.CreateNewSession — Create a Session Creates a new session after successful authentication, setting access/refresh token cookies (or headers). Called once a user is authenticated. ```go import ( "net/http" "github.com/supertokens/supertokens-golang/recipe/emailpassword" "github.com/supertokens/supertokens-golang/recipe/session" "github.com/supertokens/supertokens-golang/supertokens" ) func loginHandler(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") password := r.FormValue("password") result, err := emailpassword.SignIn("public", email, password) if err != nil { http.Error(w, err.Error(), 500) return } if result.WrongCredentialsError != nil { http.Error(w, "Invalid credentials", 401) return } // Create a new session for the authenticated user _, err = session.CreateNewSession( r, w, "public", // tenantId result.OK.User.ID, // userId map[string]interface{}{ "role": "admin", }, // accessTokenPayload (embedded in JWT) map[string]interface{}{ "signupDate": "2024-01-01", }, // sessionDataInDatabase (server-side only) ) if err != nil { http.Error(w, err.Error(), 500) return } w.WriteHeader(200) w.Write([]byte("Login successful")) } ``` ``` -------------------------------- ### session.CreateNewSessionWithoutRequestResponse Source: https://context7.com/supertokens/supertokens-golang/llms.txt Creates a session without an HTTP request/response pair, suitable for serverless environments, WebSockets, or background workers. It returns the session tokens. ```APIDOC ## session.CreateNewSessionWithoutRequestResponse ### Description Creates a session without an HTTP request/response pair, for use in serverless environments, WebSockets, or background workers. ### Method Signature `func CreateNewSessionWithoutRequestResponse(tenantId string, userId string, accessTokenPayload map[string]interface{}, sessionData map[string]interface{}, disableAntiCSRF *bool) (Session, error)` ### Parameters - **tenantId** (string) - The ID of the tenant. - **userId** (string) - The ID of the user. - **accessTokenPayload** (map[string]interface{}) - Payload to be included in the access token. - **sessionData** (map[string]interface{}) - Data to be stored server-side for the session. Can be nil. - **disableAntiCSRF** (*bool) - Pointer to a boolean to disable Anti-CSRF protection. If nil, default behavior is used. ### Returns - **Session** - The created session object. - **error** - An error if the session creation fails. ``` -------------------------------- ### Fetch SessionContainer in Twirp API Source: https://github.com/supertokens/supertokens-golang/blob/master/examples/with-twirp/README.md This Go code demonstrates how to retrieve the `SessionContainer` object within a Twirp API handler. It's crucial to check if the `SessionContainer` is `nil` to determine if a valid session exists. If a session is active, you can access user information and manage the session. ```go sessionContainer, err := GetSession(r.Context()) if err != nil { // Handle error, maybe session does not exist return nil, err } if sessionContainer == nil { // Handle case where no session exists return nil, fmt.Errorf("no session found") } userId, err := sessionContainer.GetUserID() // Example: Get User ID ```