stack/apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts
Zai Shi e5965cf977
Team frontend components (#178)
* 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>
2024-08-12 02:11:42 +02:00

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> },
}
`);
});