mirror of
https://github.com/stack-auth/stack.git
synced 2026-07-09 21:02:19 +08:00
* Team invitation (#171) * team invitation wip * implemented handler * team invitation callback wip * added team invitation frontend * fixed listCurrentUserTeamPermissions * added team invitation email template * fixed bugs * fixed verification code handler * added more checks to team invitation verification * fixed team invitation page * restructured verification code handler * fixed frontend * fixed team invitation tests * added more team invitation test * fixed bug * added migration file * removed unused code * Allow Next.js version `latest` in package.json * Fix typo * Update error message * Remove unnecessary console.warn * Updated "edit this page" button * Hide unsupported properties from docs * OAuth token tests * Fix typo * added create user button * added create user button (#173) * added basic team settings * Create SECURITY.md * added editable text * added more team settings * Export button in tables * Export all pages of tables * Update security policy * Fix docs typo * More docs typos * Improved user creation handlers * added list users on client * updated team-settings * hide team setting component for now * Fix: Improve error handling for Server API (#170) * Added entity checks to provide better errors in API for 'server' access type * Removed 'ensureUserTeamPermissionExist', changed permissionId type to string in 'ensureUserHasTeamPermission' * added different error types for user team permission --------- Co-authored-by: Fahad Khan <fahad.khan@net-mon.net> Co-authored-by: Zai Shi <zaishi00@outlook.com> * added ensureClientUserAuthenticated * improved error handling * removed unused imports * fixed bug * added member list * Sign up restriction button on dashboard Fix #66, #74 * moved data table to stack-ui * added remove user modal * fixed chokidar * updated ui * fixed merge * fixed merge * fixed merge * updated settings component * improved mobile styles * added user invitation ui * added team creation page * added team creation to team component * added setting icon to team switcher * added settings sections * added client_team_creation_enabled * added frontend team creation enabled checks * updated demo page * added member profile update * fixed profile editing * added leave team button * added create/delete team redirect * fixed column header, updated team setting * fixed account setting padding * updated tests --------- Co-authored-by: Stan Wohlwend <n2d4xc@gmail.com> Co-authored-by: Fahad Khan <62707456+kfahad5607@users.noreply.github.com> Co-authored-by: Fahad Khan <fahad.khan@net-mon.net>
388 lines
12 KiB
TypeScript
388 lines
12 KiB
TypeScript
import { it } from "../../../../../helpers";
|
|
import { Auth, InternalProjectClientKeys, Project, backendContext, niceBackendFetch } from "../../../../backend-helpers";
|
|
|
|
|
|
it("should not have have access to the project", async ({ expect }) => {
|
|
backendContext.set({ projectKeys: 'no-project' });
|
|
const response1 = await niceBackendFetch("/api/v1/internal/projects", { accessType: "client" });
|
|
expect(response1).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 400,
|
|
"body": {
|
|
"code": "ACCESS_TYPE_WITHOUT_PROJECT_ID",
|
|
"details": { "request_type": "client" },
|
|
"error": "The x-stack-access-type header was 'client', but the x-stack-project-id header was not provided.\\n\\nFor more information, see the docs on REST API authentication: https://docs.stack-auth.com/rest-api/auth#authentication",
|
|
},
|
|
"headers": Headers {
|
|
"x-stack-known-error": "ACCESS_TYPE_WITHOUT_PROJECT_ID",
|
|
<some fields may have been hidden>,
|
|
},
|
|
}
|
|
`);
|
|
});
|
|
|
|
|
|
it("is not allowed to list all current projects without signing in", async ({ expect }) => {
|
|
const response = await niceBackendFetch("/api/v1/internal/projects", { accessType: "client" });
|
|
expect(response).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 401,
|
|
"body": {
|
|
"code": "USER_AUTHENTICATION_REQUIRED",
|
|
"error": "User authentication required for this endpoint.",
|
|
},
|
|
"headers": Headers {
|
|
"x-stack-known-error": "USER_AUTHENTICATION_REQUIRED",
|
|
<some fields may have been hidden>,
|
|
},
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("lists all current projects (empty list)", async ({ expect }) => {
|
|
await Auth.Otp.signIn();
|
|
const response = await niceBackendFetch("/api/v1/internal/projects", { accessType: "client" });
|
|
expect(response).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 200,
|
|
"body": {
|
|
"is_paginated": false,
|
|
"items": [],
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("creates a new project", async ({ expect }) => {
|
|
backendContext.set({ projectKeys: InternalProjectClientKeys });
|
|
await Auth.Otp.signIn();
|
|
const result = await Project.createAndGetAdminToken({
|
|
display_name: "Test Project",
|
|
});
|
|
expect(result.createProjectResponse).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 201,
|
|
"body": {
|
|
"config": {
|
|
"allow_localhost": true,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": true,
|
|
"domains": [],
|
|
"email_config": { "type": "shared" },
|
|
"enabled_oauth_providers": [],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": false,
|
|
"oauth_providers": [],
|
|
"sign_up_enabled": true,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "",
|
|
"display_name": "Test Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": false,
|
|
"user_count": 0,
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("creates a new project with different configurations", async ({ expect }) => {
|
|
backendContext.set({ projectKeys: InternalProjectClientKeys });
|
|
await Auth.Otp.signIn();
|
|
const { createProjectResponse: response1 } = await Project.create({
|
|
display_name: "Test Project",
|
|
description: "Test description",
|
|
is_production_mode: true,
|
|
config: {
|
|
allow_localhost: false,
|
|
sign_up_enabled: false,
|
|
credential_enabled: false,
|
|
magic_link_enabled: true,
|
|
},
|
|
});
|
|
expect(response1).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 201,
|
|
"body": {
|
|
"config": {
|
|
"allow_localhost": false,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": false,
|
|
"domains": [],
|
|
"email_config": { "type": "shared" },
|
|
"enabled_oauth_providers": [],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": true,
|
|
"oauth_providers": [],
|
|
"sign_up_enabled": false,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "Test description",
|
|
"display_name": "Test Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": true,
|
|
"user_count": 0,
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
|
|
// create with oauth providers
|
|
const { createProjectResponse: response2 } = await Project.create({
|
|
display_name: "Test Project",
|
|
config: {
|
|
oauth_providers: [
|
|
{
|
|
id: "google",
|
|
type: "shared",
|
|
enabled: true,
|
|
},
|
|
{
|
|
id: "facebook",
|
|
type: "standard",
|
|
enabled: false,
|
|
client_id: "client_id",
|
|
client_secret: "client_secret",
|
|
}
|
|
]
|
|
},
|
|
});
|
|
expect(response2).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 201,
|
|
"body": {
|
|
"config": {
|
|
"allow_localhost": true,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": true,
|
|
"domains": [],
|
|
"email_config": { "type": "shared" },
|
|
"enabled_oauth_providers": [{ "id": "google" }],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": false,
|
|
"oauth_providers": [
|
|
{
|
|
"client_id": "client_id",
|
|
"client_secret": "client_secret",
|
|
"enabled": false,
|
|
"id": "facebook",
|
|
"type": "standard",
|
|
},
|
|
{
|
|
"enabled": true,
|
|
"id": "google",
|
|
"type": "shared",
|
|
},
|
|
],
|
|
"sign_up_enabled": true,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "",
|
|
"display_name": "Test Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": false,
|
|
"user_count": 0,
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
|
|
// create with shared email config
|
|
const { createProjectResponse: response3 } = await Project.create({
|
|
display_name: "Test Project",
|
|
config: {
|
|
email_config: {
|
|
type: "shared",
|
|
},
|
|
},
|
|
});
|
|
expect(response3).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 201,
|
|
"body": {
|
|
"config": {
|
|
"allow_localhost": true,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": true,
|
|
"domains": [],
|
|
"email_config": { "type": "shared" },
|
|
"enabled_oauth_providers": [],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": false,
|
|
"oauth_providers": [],
|
|
"sign_up_enabled": true,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "",
|
|
"display_name": "Test Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": false,
|
|
"user_count": 0,
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
|
|
// create with standard email config
|
|
const { createProjectResponse: response4 } = await Project.create({
|
|
display_name: "Test Project",
|
|
config: {
|
|
email_config: {
|
|
type: "standard",
|
|
host: "smtp.example.com",
|
|
port: 587,
|
|
username: "test username",
|
|
password: "test password",
|
|
sender_name: "Test Sender",
|
|
sender_email: "test@email.com",
|
|
},
|
|
},
|
|
});
|
|
expect(response4).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 201,
|
|
"body": {
|
|
"config": {
|
|
"allow_localhost": true,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": true,
|
|
"domains": [],
|
|
"email_config": {
|
|
"host": "smtp.example.com",
|
|
"password": "test password",
|
|
"port": 587,
|
|
"sender_email": "test@email.com",
|
|
"sender_name": "Test Sender",
|
|
"type": "standard",
|
|
"username": "test username",
|
|
},
|
|
"enabled_oauth_providers": [],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": false,
|
|
"oauth_providers": [],
|
|
"sign_up_enabled": true,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "",
|
|
"display_name": "Test Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": false,
|
|
"user_count": 0,
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
|
|
// create with domains
|
|
const { createProjectResponse: response5 } = await Project.create({
|
|
display_name: "Test Project",
|
|
config: {
|
|
domains: [
|
|
{
|
|
domain: 'https://domain1.com',
|
|
handler_path: '/handler1'
|
|
},
|
|
{
|
|
domain: 'https://domain2.com',
|
|
handler_path: '/handler2'
|
|
}
|
|
]
|
|
},
|
|
});
|
|
expect(response5).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 201,
|
|
"body": {
|
|
"config": {
|
|
"allow_localhost": true,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": true,
|
|
"domains": [
|
|
{
|
|
"domain": "https://domain1.com",
|
|
"handler_path": "/handler1",
|
|
},
|
|
{
|
|
"domain": "https://domain2.com",
|
|
"handler_path": "/handler2",
|
|
},
|
|
],
|
|
"email_config": { "type": "shared" },
|
|
"enabled_oauth_providers": [],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": false,
|
|
"oauth_providers": [],
|
|
"sign_up_enabled": true,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "",
|
|
"display_name": "Test Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": false,
|
|
"user_count": 0,
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("lists the current projects after creating a new project", async ({ expect }) => {
|
|
await Auth.Otp.signIn();
|
|
await Project.create();
|
|
const response = await niceBackendFetch("/api/v1/internal/projects", { accessType: "client" });
|
|
expect(response).toMatchInlineSnapshot(`
|
|
NiceResponse {
|
|
"status": 200,
|
|
"body": {
|
|
"is_paginated": false,
|
|
"items": [
|
|
{
|
|
"config": {
|
|
"allow_localhost": true,
|
|
"client_team_creation_enabled": false,
|
|
"create_team_on_sign_up": false,
|
|
"credential_enabled": true,
|
|
"domains": [],
|
|
"email_config": { "type": "shared" },
|
|
"enabled_oauth_providers": [],
|
|
"id": "<stripped UUID>",
|
|
"magic_link_enabled": false,
|
|
"oauth_providers": [],
|
|
"sign_up_enabled": true,
|
|
"team_creator_default_permissions": [{ "id": "admin" }],
|
|
"team_member_default_permissions": [{ "id": "member" }],
|
|
},
|
|
"created_at_millis": <stripped field 'created_at_millis'>,
|
|
"description": "",
|
|
"display_name": "New Project",
|
|
"id": "<stripped UUID>",
|
|
"is_production_mode": false,
|
|
"user_count": 0,
|
|
},
|
|
],
|
|
},
|
|
"headers": Headers { <some fields may have been hidden> },
|
|
}
|
|
`);
|
|
});
|