mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
8.9 KiB
8.9 KiB
Backend Design Doc
API format
- RESTful
- If
X-Stack-Override-Error-Statusheader is given and the actual response status code is 400-599, the server MUST the status code with 200, and return the actual status code in theX-Stack-Actual-Statusheader. (This is useful to prevent unwanted console error logs generated by the browser.) - If a known error (see below) occurs, the
X-Stack-Known-Errorheader MUST be returned containing the error code. The body MUST be of the shape{ code: <ERROR_CODE>, message: <HUMAN_READABLE_ERROR_MESSAGE>, details?: {<ADDITIONAL_ERROR_INFORMATION>} }. - The
X-Stack-Request-Idheader MAY be returned with a randomly generated string that can be used to identify the request in the server logs. If an error occurs, the client SHOULD include this in the message as an error code. - The server may return a
SchemaErrorif applicable, on any endpoint. This is referred to as "Common errors" in the endpoints list below.
Known errors
Terminology: "Invalid" means it was found but not valid, "Not found" means it was not found. "Error" could be anything. Make sure not to accidentally leak information, eg. "access forbidden" should often be "not found" or the user would know that the resource exists.
UnsupportedError: An error occured that is not currently supported (possibly because it was added in a version of Stack that is newer than this client). (400)SchemaError: The request body does not match the expected schema. (400)AllOverloadsFailed: This endpoint has multiple overloads, but they all failed to process the request. (400)ProjectAuthenticationError:InvalidProjectAuthentication:InvalidPublishableClientKey: The publishable key is not valid for the given project. Does the project and/or the key exist? (401)InvalidSecretServerKey: The secret server key is not valid for the given project. Does the project and/or the key exist? (401)InvalidSuperSecretAdminKey: The super secret admin key is not valid for the given project. Does the project and/or the key exist? (401)InvalidAdminAccessToken:UnparsableAdminAccessToken: Admin access token is not parsable. (401)AdminAccessTokenExpired: Admin access token has expired. Please refresh it and try again. (401)InvalidProjectForAdminAccessToken: Admin access token not valid for this project. (401)
ProjectAuthenticationRequired:ClientAuthenticationRequired: The publishable client key must be provided. (401)ServerAuthenticationRequired: The secret server key must be provided. (401)ClientOrServerAuthenticationRequired: Either the publishable client key or the secret server key must be provided. (401)ClientOrAdminAuthenticationRequired: Either the publishable client key or the super secret admin key must be provided. (401)ClientOrServerOrAdminAuthenticationRequired: Either the publishable client key, the secret server key, or the super secret admin key must be provided. (401)AdminAuthenticationRequired: The super secret admin key must be provided. (401)
ExpectedInternalProject: The project ID is expected to be internal. (401)
SessionAuthenticationError:InvalidSessionAuthentication:InvalidAccessToken: 1UnparsableAccessToken: Access token is not parsable. (401)AccessTokenExpired: Access token has expired. Please refresh it and try again. (401)InvalidProjectForAccessToken: Access token not valid for this project. (401)
SessionUserEmailNotVerified: User e-mail not verified, but is required by the project. (401)
SessionAuthenticationRequired: Session required for this request. (401)
RefreshTokenError:ProviderRejected: The provider refused to refresh their token. (401)InvalidRefreshToken: Refresh token is invalid, possibly because it has expired. A new refresh token requires reauthentication. (401)
UserEmailAlreadyExists: User already exists. (400)UserNotFound: User not found. (404)ApiKeyNotFound: API key not found. (404)ProjectNotFound: Project not found or is not accessible. (404)EmailPasswordMismatch: Wrong e-mail or password. (400)RedirectUrlNotWhitelisted: The redirect URL is not whitelisted. (400)PasswordRequirementsNotMet:PasswordTooShort: Password too short. (400)PasswordTooLong: Password too long. (400)
EmailVerificationError:EmailVerificationCodeError:EmailVerificationCodeNotFound: The e-mail verification code does not exist for this project. (404)EmailVerificationCodeExpired: The e-mail verification code has expired. (400)EmailVerificationCodeAlreadyUsed: The e-mail verification code has already been used. (400)
PasswordResetError:PasswordResetCodeError:PasswordResetCodeNotFound: The password reset code does not exist for this project. (404)PasswordResetCodeExpired: The password reset code has expired. (400)PasswordResetCodeAlreadyUsed: The password reset code has already been used. (400)
PasswordMismatch: The given password does not match the user's password. (400)
Project Authentication
- On endpoints that require project authentication, the client MUST provide:
- The project ID in the
X-Stack-Project-Idheader. - One of:
- The publishable client key in the
X-Stack-Publishable-Client-Keyheader. - The secret server key in the
X-Stack-Secret-Server-Keyheader. - The super secret admin key in the
X-Stack-Super-Secret-Admin-Keyheader. - The admin access token in the
X-Stack-Admin-Access-Tokenheader.
- The publishable client key in the
- The project ID in the
- The server MUST respond with a
InvalidProjectAuthenticationerror if there is an authentication error on the server.
Session Authentication
- On endpoints that require session authentication, the client MUST provide:
- Project authentication with client permissions.
- The access token in the
X-Stack-Access-Tokenheader.
- The server MUST respond with a
InvalidSessionAuthenticationerror if there is an authentication error on the server.
Endpoints
/api-keys- Overload 1: List or create API keys for the project.
- Methods:
GET,POST - Errors: Common errors,
InvalidProjectAuthentication,AdminAuthenticationRequired.
- Methods:
- Overload 1: List or create API keys for the project.
/api-keys/:id- Overload 1: Get, update, or delete the API key with the given ID.
- Methods:
GET,PATCH,DELETE - Errors: Common errors,
InvalidProjectAuthentication,AdminAuthenticationRequired,ApiKeyNotFound.
- Methods:
- Overload 1: Get, update, or delete the API key with the given ID.
/auth/...- not part of the rework for now
/current-project- Overload 1: Get, update, or delete the current project admin.
- Methods:
GET,PATCH,DELETE - Errors: Common errors,
InvalidProjectAuthentication,AdminAuthenticationRequired.
- Methods:
- Overload 2: Get the current client project.
- Methods:
GET - Errors: Common errors,
InvalidProjectAuthentication,ClientAuthenticationRequired.
- Methods:
- Overload 1: Get, update, or delete the current project admin.
/current-user- Overload 1: Get or update the current user.
- Methods:
GET,PATCH - Errors: Common errors,
InvalidProjectAuthentication,ClientAuthenticationRequired,SessionAuthenticationRequired.
- Methods:
- Overload 2: Get or update the current server user.
- Methods:
GET,PATCH - Errors: Common errors,
InvalidProjectAuthentication,ServerAuthenticationRequired,SessionAuthenticationRequired.
- Methods:
- Overload 1: Get or update the current user.
/projects- Overload 1: List or create projects for the current user.
- Methods:
GET,POST - Errors: Common errors,
InvalidProjectAuthentication,ClientAuthenticationRequired,ExpectedInternalProject,SessionAuthenticationRequired.
- Methods:
- Overload 1: List or create projects for the current user.
/users- Overload 1: List users in the project.
- Methods:
GET - Errors: Common errors,
InvalidProjectAuthentication,ServerAuthenticationRequired.
- Methods:
- Overload 1: List users in the project.
/users/:id- Overload 1: Get, update, or delete the user with the given ID.
- Methods:
GET,PATCH,DELETE - Errors: Common errors,
InvalidProjectAuthentication,ServerAuthenticationRequired,UserNotFound.
- Methods:
- Overload 1: Get, update, or delete the user with the given ID.
Example endpoint implementation
const requestBase = {};
const handler = smartRouteHandler(
[{ isClient: true }, { isClient: false }],
({ isClient }) => {
request: yup.object({
project: isClient ? requireClientAuthentication : requireServerAuthentication,
params: yup.object({
id: yup.string().required(),
}),
}),
response: yup.object({
status: 200,
body: yup.object({
id: yup.string().required(),
name: yup.string().required(),
...isClient ? {} : { secret: yup.string().required() },
}),
}),
handler: (obj) => {
return {
status: 200,
body: {
id: obj.params.id,
name: "John Doe",
...isClient ? {} : { secret: "super-secret" },
},
};
},
},
);
export const GET = handler;
Footnotes
-
The client SHOULD remove the access token from the client storage, and request a new one using the refresh token. ↩︎