Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
111 changes: 111 additions & 0 deletions .storybook/main.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const dirname = path.dirname(fileURLToPath(import.meta.url))

/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
stories: ['../tests/**/*.mdx', '../tests/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-docs',
'@storybook/addon-themes',
'@storybook/addon-vitest',
'msw-storybook-addon',
],
features: {
sidebarOnboardingChecklist: false,
},
core: {
disableWhatsNewNotifications: true,
},
framework: '@storybook/react-vite',
async viteFinal(config) {
return {
...config,
plugins: [
...(config.plugins || []),
{
// Real Microsoft auth can't run in Storybook (MSAL popups, device codes),
// so every import of CIPPM365OAuthButton resolves to a mock that reports
// instant auth success. Relative imports can't be object-alias'd, hence a
// resolveId hook instead of an entry in resolve.alias below.
name: 'cipp-mock-m365-oauth-button',
enforce: 'pre',
resolveId(source) {
if (source.endsWith('CippComponents/CIPPM365OAuthButton')) {
return path.resolve(dirname, '../tests/mocks/cipp-m365-oauth-button.jsx')
}
},
},
],
resolve: {
...config.resolve,
// CIPP is a Next.js app but uses @storybook/react-vite because @storybook/nextjs
// doesn't work with this project. These aliases replace Next.js modules with
// lightweight mocks so components render without a Next.js runtime.
alias: {
...config.resolve?.alias,
// stub for mui-tiptap's uninstalled required peer @tiptap/extension-image
'@tiptap/extension-image': path.resolve(
dirname,
'../tests/mocks/tiptap-extension-image.js',
),
'next/dynamic': path.resolve(dirname, '../tests/mocks/next-dynamic.js'),
'next/router': path.resolve(dirname, '../tests/mocks/next-router.js'),
'next/navigation': path.resolve(dirname, '../tests/mocks/next-navigation.js'),
'next/head': path.resolve(dirname, '../tests/mocks/next-head.js'),
'next/image': path.resolve(dirname, '../tests/mocks/next-image.js'),
'next/link': path.resolve(dirname, '../tests/mocks/next-link.js'),
},
},
define: {
...(config.define || {}),
// Next.js components reference process.env and global, these don't exist in a
// pure Vite browser context, so we shim them to avoid ReferenceErrors.
'process.env': '{}',
global: 'window',
},
esbuild: {
...config.esbuild,
// The codebase uses .js files with JSX syntax. Vite's default esbuild loader
// only handles JSX in .jsx files, so we override the loader for all .js files.
jsx: 'automatic',
jsxImportSource: 'react',
loader: 'jsx',
include: /(src|tests|\.storybook)\/.*\.(js|jsx)$/,
exclude: [],
},
build: {
...config.build,
rollupOptions: {
...config.build?.rollupOptions,
onwarn(warning, warn) {
// Suppress "use client" directive warnings from React Server Components-aware
// libraries (e.g. @mui/material). These directives are harmless in Storybook
// since everything runs client-side, but Rollup treats them as errors.
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') return
warn(warning)
},
},
},
optimizeDeps: {
...config.optimizeDeps,
// Same JSX-in-.js fix as above, but for Vite's dependency pre-bundling step
// (esbuild runs separately for optimizeDeps vs transform).
esbuildOptions: {
...config.optimizeDeps?.esbuildOptions,
jsx: 'automatic',
jsxImportSource: 'react',
loader: {
'.js': 'jsx',
'.jsx': 'jsx',
},
},
},
}
},
staticDirs: ['../public'],
}

export default config
107 changes: 107 additions & 0 deletions .storybook/preview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react'
import { ThemeProvider } from '@mui/material/styles'
import CssBaseline from '@mui/material/CssBaseline'
import { withThemeFromJSXProvider } from '@storybook/addon-themes'
import { Provider } from 'react-redux'
import { configureStore } from '@reduxjs/toolkit'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { setupWorker } from 'msw/browser'
import { mswLoader } from 'msw-storybook-addon/csf3'
import { LocalizationProvider } from '@mui/x-date-pickers'
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'
import TimeAgo from 'javascript-time-ago'
import en from 'javascript-time-ago/locale/en.json'
import { createTheme } from '../src/theme'
import { SettingsContext } from '../src/contexts/settings-context'
import { handlers } from '../tests/mocks/handlers'
// require.context polyfill must load in the storybook dev server too, the vitest
// setup files don't run there
import '../tests/mocks/require-context'

const mockSettings = {
currentTenant: 'testdomain.com',
currentTheme: { value: 'light', label: 'light' },
paletteMode: 'light',
direction: 'ltr',
pinNav: true,
showDevtools: false,
handleUpdate: () => {},
handleReset: () => {},
isCustom: false,
}

TimeAgo.addDefaultLocale(en)

const darkTheme = createTheme({
colorPreset: 'orange',
direction: 'ltr',
paletteMode: 'dark',
contrast: 'high',
})

const lightTheme = createTheme({
colorPreset: 'orange',
direction: 'ltr',
paletteMode: 'light',
contrast: 'high',
})

const mockStore = configureStore({
reducer: {
toasts: (state = { toasts: [] }) => state,
},
})

/** @type { import('@storybook/react').Preview } */
const preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
msw: {
handlers,
},
},
// custom setup instead of the addon default: 'bypass' silences MSW warnings for
// unhandled requests (Vite module imports, static assets, unmocked /api routes),
// 'quiet' suppresses console logging for handled requests
loaders: [
mswLoader(async () => {
const worker = setupWorker()
await worker.start({ onUnhandledRequest: 'bypass', quiet: true })
return worker
}),
],
decorators: [
withThemeFromJSXProvider({
themes: {
light: lightTheme,
dark: darkTheme,
},
defaultTheme: 'light',
Provider: ThemeProvider,
GlobalStyles: CssBaseline,
}),
(Story) => {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
return (
<Provider store={mockStore}>
<QueryClientProvider client={queryClient}>
<SettingsContext.Provider value={mockSettings}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Story />
</LocalizationProvider>
</SettingsContext.Provider>
</QueryClientProvider>
</Provider>
)
},
],
}

export default preview
5 changes: 5 additions & 0 deletions .storybook/vitest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { configure } from 'storybook/test'
import '../tests/mocks/require-context'

// coverage instrumentation slows lazy chunks and fetches past the 1s default
configure({ asyncUtilTimeout: 10000 })
7 changes: 7 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ const eslintConfig = defineConfig([
],
},
},
{
// csf meta is an anonymous default export by convention
files: ['tests/**/*.stories.jsx', '.storybook/**'],
rules: {
'import/no-anonymous-default-export': 'off',
},
},
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
Expand Down
64 changes: 50 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "cipp",
"version": "10.7.5",
"version": "10.8.1",
"author": "CIPP Contributors",
"homepage": "https://cipp.app/",
"bugs": {
"url": "https://github.com/CyberDrain/CIPP/issues"
},
"license": "AGPL-3.0",
"engines": {
"node": "^22.13.0"
"node": "^22.22.0"
},
"repository": {
"type": "git",
Expand All @@ -22,7 +22,16 @@
"lint": "npx eslint .",
"lint-fix": "npx eslint . --fix",
"prettier": "prettier --write '**/*.{js,jsx,json}'",
"start-swa": "swa start --swa-config-location .vscode http://127.0.0.1:3000 --api-location http://127.0.0.1:7071 --verbose=silly"
"start-swa": "swa start --swa-config-location .vscode http://127.0.0.1:3000 --api-location http://127.0.0.1:7071 --verbose=silly",
"storybook": "storybook dev -p 6006 --no-open",
"storybook-build": "npx storybook build -o build-storybook",
"storybook-serve": "npx http-server build-storybook -p 6006",
"test": "vitest run",
"test:watch": "vitest",
"test:unit": "vitest run --project unit",
"test:browser": "vitest run --project storybook --browser.headless=false",
"test:coverage": "vitest run --coverage --testTimeout=30000",
"test:storybook": "vitest run --project storybook"
},
"dependencies": {
"@emotion/cache": "11.14.0",
Expand All @@ -35,7 +44,7 @@
"@mui/lab": "7.0.0-beta.17",
"@mui/material": "7.3.10",
"@mui/system": "7.3.10",
"@mui/x-date-pickers": "^9.0.2",
"@mui/x-date-pickers": "^9.10.1",
"@musement/iso-duration": "^1.0.0",
"@nivo/core": "^0.99.0",
"@nivo/sankey": "^0.99.0",
Expand All @@ -46,14 +55,14 @@
"@tanstack/react-query-devtools": "^5.101.2",
"@tanstack/react-query-persist-client": "^5.101.2",
"@tanstack/react-table": "^8.19.2",
"@tiptap/core": "^3.22.3",
"@tiptap/extension-heading": "^3.22.3",
"@tiptap/core": "^3.29.2",
"@tiptap/extension-heading": "^3.27.3",
"@tiptap/extension-table": "^3.20.5",
"@tiptap/pm": "^3.27.3",
"@tiptap/pm": "^3.29.2",
"@tiptap/react": "^3.20.5",
"@tiptap/starter-kit": "^3.20.5",
"@vvo/tzdb": "^6.198.0",
"apexcharts": "5.16.0",
"apexcharts": "6.6.1",
"axios": "1.18.1",
"date-fns": "4.4.0",
"diff": "^9.0.0",
Expand All @@ -73,15 +82,15 @@
"material-react-table": "^3.0.1",
"monaco-editor": "^0.55.1",
"mui-tiptap": "^1.31.0",
"next": "^16.2.10",
"next": "^16.2.11",
"nprogress": "0.2.0",
"numeral": "2.0.6",
"prop-types": "15.8.1",
"punycode": "^2.3.1",
"react": "19.2.6",
"react": "19.2.8",
"react-apexcharts": "2.1.1",
"react-beautiful-dnd": "13.1.1",
"react-dom": "19.2.6",
"react-dom": "19.2.8",
"react-dropzone": "15.0.0",
"react-error-boundary": "^6.1.2",
"react-hook-form": "^7.76.1",
Expand All @@ -106,15 +115,42 @@
"simplebar": "6.3.3",
"simplebar-react": "3.3.2",
"stylis-plugin-rtl": "2.1.1",
"swagger-ui-dist": "5.32.12",
"unified": "^11.0.5",
"yup": "1.7.1"
},
"devDependencies": {
"@storybook/addon-a11y": "10.3.5",
"@storybook/addon-docs": "10.3.5",
"@storybook/addon-themes": "10.3.5",
"@storybook/addon-vitest": "10.3.5",
"@storybook/react-vite": "10.3.5",
"@svgr/webpack": "8.1.0",
"@testing-library/dom": "10.4.1",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.1",
"@vitest/browser-playwright": "4.1.10",
"@vitest/coverage-v8": "4.1.10",
"eslint": "^9.39.4",
"eslint-config-next": "^16.2.10",
"eslint-config-prettier": "^10.1.8",
"prettier": "^3.9.5",
"typescript": "5.9.3"
"jsdom": "29.0.1",
"msw": "2.12.14",
"msw-storybook-addon": "3.0.0",
"playwright": "1.59.1",
"prettier": "^3.9.6",
"storybook": "10.3.5",
"typescript": "5.9.3",
"vite": "7.3.6",
"vitest": "4.1.10"
},
"msw": {
"workerDirectory": [
"public"
]
},
"resolutions": {
"vite": "7.3.6"
}
}
}
Binary file added public/cippy-401.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cippy-404.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cippy-500.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/cippy-auth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/intune-definitions/00/0005db2dca15a26a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"user_vendor_msft_policy_config_excel16v5~policy~l_microsoftofficeexcel~l_filetab~l_checkaccessibility_l_stopcheckingtablealttextaccessibilityinformation","displayName":"Stop checking for table alt text accessibility information (User)","description":"This policy setting prevents the Accessibility Checker from verifying that tables contain alternative text.\r\n\r\nIf you enable this policy setting, the Accessibility Checker will be prevented from verifying that tables contain alternative text.\r\n\r\nIf you disable or do not configure this policy setting, tables will be checked for alternative text and any issues will appear in the Accessibility Checker.","helpText":"","infoUrls":[],"categoryId":"d9b5c806-099f-4be8-96e4-1152e99cbf26","categoryName":"Check Accessibility","options":[{"id":"user_vendor_msft_policy_config_excel16v5~policy~l_microsoftofficeexcel~l_filetab~l_checkaccessibility_l_stopcheckingtablealttextaccessibilityinformation_0","displayName":"Disabled","description":null,"helpText":null},{"id":"user_vendor_msft_policy_config_excel16v5~policy~l_microsoftofficeexcel~l_filetab~l_checkaccessibility_l_stopcheckingtablealttextaccessibilityinformation_1","displayName":"Enabled","description":null,"helpText":null}]}
1 change: 1 addition & 0 deletions public/intune-definitions/00/0005fe387917425e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"device_vendor_msft_policy_config_updateupdates.1~policy~cat_edgeupdate~cat_applications~cat_microsoftedgebeta_pol_allowinstallationmicrosoftedgebeta","displayName":"Allow installation","description":"Specifies whether a Microsoft Edge channel can be installed on domain-joined devices.\r\n\r\n If you enable this policy for a channel, Microsoft Edge will not be blocked from installation.\r\n\r\n If you disable this policy for a channel (or set it to 'Installs disabled'), Microsoft Edge will be blocked from installation.\r\n\r\n If you don't configure this policy for a channel, the 'Allow installation default' policy configuration determines whether users can install that channel of Microsoft Edge.\r\n\r\nIf you set this policy to Always allow Machine-Wide Installs but not Per-User Installs, Microsoft Edge Beta will only be deployed machine-wide.\r\n\r\nIf you set this policy to Force Installs (Machine-Wide), Microsoft Edge Beta may only be deployed machine-wide if Microsoft Edge Update is pre-installed. Requires Microsoft Edge Update 1.3.155.43 or higher.\r\n\r\nIf you set this policy to Force Installs (Per-User), Microsoft Edge Beta may only be deployed on a Per-User basis to all machines if Microsoft Edge Update is pre-installed Per-User. Requires Microsoft Edge Update 1.3.155.43 or higher.\r\n\r\nThis policy is available only on Windows instances that are joined to a Microsoft庐 Active Directory庐 domain.","helpText":"","infoUrls":[],"categoryId":"7b91ab31-7ed5-4de9-bd49-d04303fd3c74","categoryName":"Microsoft Edge Beta","options":[{"id":"device_vendor_msft_policy_config_updateupdates.1~policy~cat_edgeupdate~cat_applications~cat_microsoftedgebeta_pol_allowinstallationmicrosoftedgebeta_0","displayName":"Disabled","description":null,"helpText":null},{"id":"device_vendor_msft_policy_config_updateupdates.1~policy~cat_edgeupdate~cat_applications~cat_microsoftedgebeta_pol_allowinstallationmicrosoftedgebeta_1","displayName":"Enabled","description":null,"helpText":null}]}
1 change: 1 addition & 0 deletions public/intune-definitions/00/000cbe14a3ced6ee.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"device_vendor_msft_laps_policies_backupdirectory","displayName":"Backup Directory ","description":"Use this setting to configure which directory the local admin account password is backed up to.\n\nThe allowable settings are:\n\n0=Disabled (password will not be backed up)\n1=Backup the password to Microsoft Entra ID only\n2=Backup the password to Active Directory only\n\nIf not specified, this setting will default to 0.\r\n","helpText":"","infoUrls":["https://docs.microsoft.com/windows/client-management/mdm/LAPS-csp/"],"categoryId":"f1dcf7b6-2d89-41bf-b5eb-02a879c6db5d","categoryName":null,"options":[{"id":"device_vendor_msft_laps_policies_backupdirectory_0","displayName":"Disabled (password will not be backed up)","description":"Disabled (password will not be backed up)","helpText":null},{"id":"device_vendor_msft_laps_policies_backupdirectory_1","displayName":"Backup the password to Microsoft Entra ID only","description":"Backup the password to Microsoft Entra ID only","helpText":null},{"id":"device_vendor_msft_laps_policies_backupdirectory_2","displayName":"Backup the password to Active Directory only","description":"Backup the password to Active Directory only","helpText":null}]}
1 change: 1 addition & 0 deletions public/intune-definitions/00/0015fb85c2bfb032.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"user_vendor_msft_policy_config_outlk16v6~policy~l_microsoftofficeoutlook~l_toolsaccounts~l_exchangesettings_l_authenticationwithexchangeserver_v2_l_selecttheauthenticationwithexchangeserver","displayName":"Select the authentication with Exchange server. (User)","description":"","helpText":"","infoUrls":[],"categoryId":"d4e5541e-ab77-4e6c-8046-1fb80ee705ad","categoryName":"Security Form Settings","options":[{"id":"user_vendor_msft_policy_config_outlk16v6~policy~l_microsoftofficeoutlook~l_toolsaccounts~l_exchangesettings_l_authenticationwithexchangeserver_v2_l_selecttheauthenticationwithexchangeserver_9","displayName":"Kerberos/NTLM Password Authentication","description":null,"helpText":null},{"id":"user_vendor_msft_policy_config_outlk16v6~policy~l_microsoftofficeoutlook~l_toolsaccounts~l_exchangesettings_l_authenticationwithexchangeserver_v2_l_selecttheauthenticationwithexchangeserver_16","displayName":"Kerberos Password Authentication","description":null,"helpText":null},{"id":"user_vendor_msft_policy_config_outlk16v6~policy~l_microsoftofficeoutlook~l_toolsaccounts~l_exchangesettings_l_authenticationwithexchangeserver_v2_l_selecttheauthenticationwithexchangeserver_10","displayName":"NTLM Password Authentication","description":null,"helpText":null},{"id":"user_vendor_msft_policy_config_outlk16v6~policy~l_microsoftofficeoutlook~l_toolsaccounts~l_exchangesettings_l_authenticationwithexchangeserver_v2_l_selecttheauthenticationwithexchangeserver_2147545088","displayName":"Insert a smart card","description":null,"helpText":null}]}
1 change: 1 addition & 0 deletions public/intune-definitions/00/0016b9201a4e64c7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"device_vendor_msft_policy_config_chromeintunev1~policy~googlechrome~removedpolicies_renderinhostlist_renderinhostlistdesc","displayName":"Always render the following URL patterns in the host browser (Device)","description":"","helpText":"","infoUrls":[],"categoryId":"3634c01b-1a85-4f50-9f52-63bc10bf0e39","categoryName":"Removed policies","options":null}
1 change: 1 addition & 0 deletions public/intune-definitions/00/0018317efccd6e0a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"user_vendor_msft_policy_config_excel16v2~policy~l_microsoftofficeexcel~l_miscellaneous168_l_personaltemplatespath","displayName":"Personal templates path for Excel (User)","description":"This policy setting specifies the location of a user's personal templates. \r\n\r\nIf you enable this policy setting, users will see any templates they have saved in the specified location in the custom templates tab on the Office Start screen and in File | New and when saving a template their default folder will change to be the specified location. \r\n\r\nIf you disable or do not configure this policy setting, users will not see templates they have saved in the custom templates tab on the Office Start screen and in File | New and when saving a template their default folder will be their document save location.","helpText":"","infoUrls":[],"categoryId":"bc58391f-664c-42dd-9d18-269e65f324a7","categoryName":"Miscellaneous","options":[{"id":"user_vendor_msft_policy_config_excel16v2~policy~l_microsoftofficeexcel~l_miscellaneous168_l_personaltemplatespath_0","displayName":"Disabled","description":null,"helpText":null},{"id":"user_vendor_msft_policy_config_excel16v2~policy~l_microsoftofficeexcel~l_miscellaneous168_l_personaltemplatespath_1","displayName":"Enabled","description":null,"helpText":null}]}
Loading
Loading