@ant-design/icons#ProfileOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#ProfileOutlined.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx From shippo with MIT License | 6 votes |
My = () => {
const history = useNavigate()
return (
<Container direction="vertical">
<Header
style={{
height: '45px',
lineHeight: '45px',
backgroundColor: '#fff',
textAlign: 'center',
fontSize: '18px',
}}
>
我
</Header>
<WhiteSpace size={15} />
<Main>
<UserInfoCard />
<WhiteSpace size={15} />
<List>
<List.Item prefix={<BellOutlined />} onClick={() => {}}>
通知
</List.Item>
<List.Item prefix={<ProfileOutlined />} onClick={() => {}}>
我的作品
</List.Item>
<List.Item prefix={<SettingOutlined />} onClick={() => history('/setting')}>
设置
</List.Item>
</List>
</Main>
</Container>
)
}
Example #2
Source File: Icon.tsx From html2sketch with MIT License | 4 votes |
IconSymbol: FC = () => {
return (
<Row>
{/*<CaretUpOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/1.CaretUpOutlined'}*/}
{/*/>*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.MailOutlined'}*/}
{/*/>*/}
{/*<StepBackwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
{/*<StepForwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
<StepForwardOutlined />
<ShrinkOutlined />
<ArrowsAltOutlined />
<DownOutlined />
<UpOutlined />
<LeftOutlined />
<RightOutlined />
<CaretUpOutlined />
<CaretDownOutlined />
<CaretLeftOutlined />
<CaretRightOutlined />
<VerticalAlignTopOutlined />
<RollbackOutlined />
<FastBackwardOutlined />
<FastForwardOutlined />
<DoubleRightOutlined />
<DoubleLeftOutlined />
<VerticalLeftOutlined />
<VerticalRightOutlined />
<VerticalAlignMiddleOutlined />
<VerticalAlignBottomOutlined />
<ForwardOutlined />
<BackwardOutlined />
<EnterOutlined />
<RetweetOutlined />
<SwapOutlined />
<SwapLeftOutlined />
<SwapRightOutlined />
<ArrowUpOutlined />
<ArrowDownOutlined />
<ArrowLeftOutlined />
<ArrowRightOutlined />
<LoginOutlined />
<LogoutOutlined />
<MenuFoldOutlined />
<MenuUnfoldOutlined />
<BorderBottomOutlined />
<BorderHorizontalOutlined />
<BorderInnerOutlined />
<BorderOuterOutlined />
<BorderLeftOutlined />
<BorderRightOutlined />
<BorderTopOutlined />
<BorderVerticleOutlined />
<PicCenterOutlined />
<PicLeftOutlined />
<PicRightOutlined />
<RadiusBottomleftOutlined />
<RadiusBottomrightOutlined />
<RadiusUpleftOutlined />
<RadiusUprightOutlined />
<FullscreenOutlined />
<FullscreenExitOutlined />
<QuestionOutlined />
<PauseOutlined />
<MinusOutlined />
<PauseCircleOutlined />
<InfoOutlined />
<CloseOutlined />
<ExclamationOutlined />
<CheckOutlined />
<WarningOutlined />
<IssuesCloseOutlined />
<StopOutlined />
<EditOutlined />
<CopyOutlined />
<ScissorOutlined />
<DeleteOutlined />
<SnippetsOutlined />
<DiffOutlined />
<HighlightOutlined />
<AlignCenterOutlined />
<AlignLeftOutlined />
<AlignRightOutlined />
<BgColorsOutlined />
<BoldOutlined />
<ItalicOutlined />
<UnderlineOutlined />
<StrikethroughOutlined />
<RedoOutlined />
<UndoOutlined />
<ZoomInOutlined />
<ZoomOutOutlined />
<FontColorsOutlined />
<FontSizeOutlined />
<LineHeightOutlined />
<SortAscendingOutlined />
<SortDescendingOutlined />
<DragOutlined />
<OrderedListOutlined />
<UnorderedListOutlined />
<RadiusSettingOutlined />
<ColumnWidthOutlined />
<ColumnHeightOutlined />
<AreaChartOutlined />
<PieChartOutlined />
<BarChartOutlined />
<DotChartOutlined />
<LineChartOutlined />
<RadarChartOutlined />
<HeatMapOutlined />
<FallOutlined />
<RiseOutlined />
<StockOutlined />
<BoxPlotOutlined />
<FundOutlined />
<SlidersOutlined />
<AndroidOutlined />
<AppleOutlined />
<WindowsOutlined />
<IeOutlined />
<ChromeOutlined />
<GithubOutlined />
<AliwangwangOutlined />
<DingdingOutlined />
<WeiboSquareOutlined />
<WeiboCircleOutlined />
<TaobaoCircleOutlined />
<Html5Outlined />
<WeiboOutlined />
<TwitterOutlined />
<WechatOutlined />
<AlipayCircleOutlined />
<TaobaoOutlined />
<SkypeOutlined />
<FacebookOutlined />
<CodepenOutlined />
<CodeSandboxOutlined />
<AmazonOutlined />
<GoogleOutlined />
<AlipayOutlined />
<AntDesignOutlined />
<AntCloudOutlined />
<ZhihuOutlined />
<SlackOutlined />
<SlackSquareOutlined />
<BehanceSquareOutlined />
<DribbbleOutlined />
<DribbbleSquareOutlined />
<InstagramOutlined />
<YuqueOutlined />
<AlibabaOutlined />
<YahooOutlined />
<RedditOutlined />
<SketchOutlined />
<AccountBookOutlined />
<AlertOutlined />
<ApartmentOutlined />
<ApiOutlined />
<QqOutlined />
<MediumWorkmarkOutlined />
<GitlabOutlined />
<MediumOutlined />
<GooglePlusOutlined />
<AppstoreAddOutlined />
<AppstoreOutlined />
<AudioOutlined />
<AudioMutedOutlined />
<AuditOutlined />
<BankOutlined />
<BarcodeOutlined />
<BarsOutlined />
<BellOutlined />
<BlockOutlined />
<BookOutlined />
<BorderOutlined />
<BranchesOutlined />
<BuildOutlined />
<BulbOutlined />
<CalculatorOutlined />
<CalendarOutlined />
<CameraOutlined />
<CarOutlined />
<CarryOutOutlined />
<CiCircleOutlined />
<CiOutlined />
<CloudOutlined />
<ClearOutlined />
<ClusterOutlined />
<CodeOutlined />
<CoffeeOutlined />
<CompassOutlined />
<CompressOutlined />
<ContactsOutlined />
<ContainerOutlined />
<ControlOutlined />
<CopyrightCircleOutlined />
<CopyrightOutlined />
<CreditCardOutlined />
<CrownOutlined />
<CustomerServiceOutlined />
<DashboardOutlined />
<DatabaseOutlined />
<DeleteColumnOutlined />
<DeleteRowOutlined />
<DisconnectOutlined />
<DislikeOutlined />
<DollarCircleOutlined />
<DollarOutlined />
<DownloadOutlined />
<EllipsisOutlined />
<EnvironmentOutlined />
<EuroCircleOutlined />
<EuroOutlined />
<ExceptionOutlined />
<ExpandAltOutlined />
<ExpandOutlined />
<ExperimentOutlined />
<ExportOutlined />
<EyeOutlined />
<FieldBinaryOutlined />
<FieldNumberOutlined />
<FieldStringOutlined />
<DesktopOutlined />
<DingtalkOutlined />
<FileAddOutlined />
<FileDoneOutlined />
<FileExcelOutlined />
<FileExclamationOutlined />
<FileOutlined />
<FileImageOutlined />
<FileJpgOutlined />
<FileMarkdownOutlined />
<FilePdfOutlined />
<FilePptOutlined />
<FileProtectOutlined />
<FileSearchOutlined />
<FileSyncOutlined />
<FileTextOutlined />
<FileUnknownOutlined />
<FileWordOutlined />
<FilterOutlined />
<FireOutlined />
<FlagOutlined />
<FolderAddOutlined />
<FolderOutlined />
<FolderOpenOutlined />
<ForkOutlined />
<FormatPainterOutlined />
<FrownOutlined />
<FunctionOutlined />
<FunnelPlotOutlined />
<GatewayOutlined />
<GifOutlined />
<GiftOutlined />
<GlobalOutlined />
<GoldOutlined />
<GroupOutlined />
<HddOutlined />
<HeartOutlined />
<HistoryOutlined />
<HomeOutlined />
<HourglassOutlined />
<IdcardOutlined />
<ImportOutlined />
<InboxOutlined />
<InsertRowAboveOutlined />
<InsertRowBelowOutlined />
<InsertRowLeftOutlined />
<InsertRowRightOutlined />
<InsuranceOutlined />
<InteractionOutlined />
<KeyOutlined />
<LaptopOutlined />
<LayoutOutlined />
<LikeOutlined />
<LineOutlined />
<LinkOutlined />
<Loading3QuartersOutlined />
<LoadingOutlined />
<LockOutlined />
<MailOutlined />
<ManOutlined />
<MedicineBoxOutlined />
<MehOutlined />
<MenuOutlined />
<MergeCellsOutlined />
<MessageOutlined />
<MobileOutlined />
<MoneyCollectOutlined />
<MonitorOutlined />
<MoreOutlined />
<NodeCollapseOutlined />
<NodeExpandOutlined />
<NodeIndexOutlined />
<NotificationOutlined />
<NumberOutlined />
<PaperClipOutlined />
<PartitionOutlined />
<PayCircleOutlined />
<PercentageOutlined />
<PhoneOutlined />
<PictureOutlined />
<PoundCircleOutlined />
<PoundOutlined />
<PoweroffOutlined />
<PrinterOutlined />
<ProfileOutlined />
<ProjectOutlined />
<PropertySafetyOutlined />
<PullRequestOutlined />
<PushpinOutlined />
<QrcodeOutlined />
<ReadOutlined />
<ReconciliationOutlined />
<RedEnvelopeOutlined />
<ReloadOutlined />
<RestOutlined />
<RobotOutlined />
<RocketOutlined />
<SafetyCertificateOutlined />
<SafetyOutlined />
<ScanOutlined />
<ScheduleOutlined />
<SearchOutlined />
<SecurityScanOutlined />
<SelectOutlined />
<SendOutlined />
<SettingOutlined />
<ShakeOutlined />
<ShareAltOutlined />
<ShopOutlined />
<ShoppingCartOutlined />
<ShoppingOutlined />
<SisternodeOutlined />
<SkinOutlined />
<SmileOutlined />
<SolutionOutlined />
<SoundOutlined />
<SplitCellsOutlined />
<StarOutlined />
<SubnodeOutlined />
<SyncOutlined />
<TableOutlined />
<TabletOutlined />
<TagOutlined />
<TagsOutlined />
<TeamOutlined />
<ThunderboltOutlined />
<ToTopOutlined />
<ToolOutlined />
<TrademarkCircleOutlined />
<TrademarkOutlined />
<TransactionOutlined />
<TrophyOutlined />
<UngroupOutlined />
<UnlockOutlined />
<UploadOutlined />
<UsbOutlined />
<UserAddOutlined />
<UserDeleteOutlined />
<UserOutlined />
<UserSwitchOutlined />
<UsergroupAddOutlined />
<UsergroupDeleteOutlined />
<VideoCameraOutlined />
<WalletOutlined />
<WifiOutlined />
<BorderlessTableOutlined />
<WomanOutlined />
<BehanceOutlined />
<DropboxOutlined />
<DeploymentUnitOutlined />
<UpCircleOutlined />
<DownCircleOutlined />
<LeftCircleOutlined />
<RightCircleOutlined />
<UpSquareOutlined />
<DownSquareOutlined />
<LeftSquareOutlined />
<RightSquareOutlined />
<PlayCircleOutlined />
<QuestionCircleOutlined />
<PlusCircleOutlined />
<PlusSquareOutlined />
<MinusSquareOutlined />
<MinusCircleOutlined />
<InfoCircleOutlined />
<ExclamationCircleOutlined />
<CloseCircleOutlined />
<CloseSquareOutlined />
<CheckCircleOutlined />
<CheckSquareOutlined />
<ClockCircleOutlined />
<FormOutlined />
<DashOutlined />
<SmallDashOutlined />
<YoutubeOutlined />
<CodepenCircleOutlined />
<AliyunOutlined />
<PlusOutlined />
<LinkedinOutlined />
<AimOutlined />
<BugOutlined />
<CloudDownloadOutlined />
<CloudServerOutlined />
<CloudSyncOutlined />
<CloudUploadOutlined />
<CommentOutlined />
<ConsoleSqlOutlined />
<EyeInvisibleOutlined />
<FileGifOutlined />
<DeliveredProcedureOutlined />
<FieldTimeOutlined />
<FileZipOutlined />
<FolderViewOutlined />
<FundProjectionScreenOutlined />
<FundViewOutlined />
<MacCommandOutlined />
<PlaySquareOutlined />
<OneToOneOutlined />
<RotateLeftOutlined />
<RotateRightOutlined />
<SaveOutlined />
<SwitcherOutlined />
<TranslationOutlined />
<VerifiedOutlined />
<VideoCameraAddOutlined />
<WhatsAppOutlined />
{/*</Col>*/}
</Row>
);
}
Example #3
Source File: ProviderSample.tsx From next-basics with GNU General Public License v3.0 | 4 votes |
export function ProviderSample(props: ProviderSampleProps): React.ReactElement {
const { t } = useTranslation(NS_DEVELOPERS);
const [curIndex, setCurIndex] = useState(0);
const { examples = [], endpoint } = props;
const getHeaderInfo = useCallback(
(headers: Record<string, string> = {}): React.ReactElement => {
return (
<dl>
{Object.entries(headers).map(([key, value]) => (
<>
<dt>{key}:</dt>
<dd>{value}</dd>
</>
))}
</dl>
);
},
[]
);
const request = useMemo(
() => examples[curIndex]?.request,
[examples, curIndex]
);
const response = useMemo(
() => examples[curIndex]?.response,
[examples, curIndex]
);
const handlerChange = (value: number): void => {
setCurIndex(value);
};
const renderContent = (content: string): React.ReactElement => {
return (
<div className={styles.terminalWrapper}>
<pre className={styles.terminal}>
<code>{content}</code>
<div className={styles.toolbar}>
<span className={styles.copyIcon}>
<Clipboard
text={content}
icon={{ theme: "outlined" }}
onCopy={() => message.success(t(K.COPY_SUCCESS))}
/>
</span>
</div>
</pre>
</div>
);
};
return (
<div className={styles.container}>
<Select
onChange={handlerChange}
value={curIndex}
style={{ width: 300 }}
getPopupContainer={(triggerNode) => triggerNode.parentElement}
>
{examples?.map((item, index) => (
<Select.Option key={index} value={index}>
{i18nText(item.description)}
</Select.Option>
))}
</Select>
<div>
<h4 className={styles.title}>
{t(K.REQUEST_SAMPLE)}{" "}
{request?.headers && (
<Popover
overlayClassName={styles.customPopoverOverlay}
overlayInnerStyle={{ minWidth: overlayInnerWidth }}
title={<span className={styles.header}>Request Headers</span>}
content={getHeaderInfo(request.headers)}
>
<ProfileOutlined />
</Popover>
)}
</h4>
{renderContent(
request?.method && request?.uri
? `${request.method} ${request.uri}`
: endpoint
)}
{request?.body && renderContent(request.body)}
</div>
{response?.body && (
<div>
<h4 className={styles.title}>
{t(K.RESPONSE_SAMPLE)}{" "}
<Popover
overlayClassName={styles.customPopoverOverlay}
overlayInnerStyle={{ minWidth: overlayInnerWidth }}
title={<span className={styles.header}>Response Headers</span>}
content={getHeaderInfo(response.headers)}
>
<ProfileOutlined />
</Popover>
</h4>
{renderContent(response.body)}
</div>
)}
</div>
);
}
Example #4
Source File: index.tsx From visual-layout with MIT License | 4 votes |
NodeTree = () => {
const [search, setSearch] = useState('');
const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState(true);
const { appService, refresh } = useContext(AppContext);
const page = appService.project.getCurrentPage();
useEffect(() => {
setAutoExpandParent(true);
setExpandedKeys([
// @ts-ignore
...new Set([
...expandedKeys,
...(page?.currentNode.map(({ id }) => id) || []),
]),
]);
// eslint-disable-next-line
}, [appService.project, page?.currentNode[0]]);
const trees = useMemo((): DataNode[] => {
const getTree = (node: NodeService | string, id?: number): DataNode => {
if (isString(node)) {
return {
title: node,
key: `${id}:${node}`,
icon: (
<Tooltip placement="right" title="Text">
<ProfileOutlined />
</Tooltip>
),
};
} else {
const { id, _name, type, children } = node;
nodeKeyId.set(id, node);
return {
title: `${_name}`,
key: id,
icon: ({ selected }) =>
selected ? (
<CheckCircleTwoTone twoToneColor="#52c41a" />
) : type === 'Component' ? (
<Tooltip placement="right" title="Component">
<AppstoreOutlined />
</Tooltip>
) : (
<Tooltip placement="right" title="Element">
<BuildOutlined />
</Tooltip>
),
children: isString(children)
? [
{
title: children,
key: `${id}:${children}`,
icon: (
<Tooltip placement="right" title="Text">
<ProfileOutlined />
</Tooltip>
),
},
]
: (children
?.map(child => child && getTree(child, id))
.filter(_ => _) as DataNode[]),
};
}
};
return page?.page ? [getTree(page.page)] : [];
// eslint-disable-next-line
}, [refresh, page?.page]);
const filter = (treeData: DataNode[]): DataNode[] => {
function matchSearch<T extends string>(title: T): boolean {
return !search || new RegExp(_.escapeRegExp(search), 'ig').test(title);
}
return treeData
.map(tree => {
const { title, children } = tree;
tree.children = children && filter(children);
if (tree.children?.length || matchSearch(title as string)) {
return tree;
}
return false;
})
.filter(_ => _) as DataNode[];
};
return (
<div className={styles.container}>
<div className={styles.search}>
<Input.Search
placeholder="Search Node"
onChange={e => setSearch(e.target.value)}
/>
</div>
<div className={styles.scrollWarper}>
<Tree
showIcon
onSelect={(_, { node }) => {
if (node) {
const nodeService = nodeKeyId.get(node.key);
if (nodeService) {
page.setCurrentNode([nodeService]);
}
}
}}
showLine={{ showLeafIcon: false }}
selectedKeys={
appService.project.getCurrentPage()?.currentNode.map(({ id }) => id) ||
[]
}
autoExpandParent={autoExpandParent}
expandedKeys={expandedKeys}
onExpand={expandedKeysValue => {
setAutoExpandParent(false);
setExpandedKeys(expandedKeysValue);
}}
treeData={filter(cloneJsxObject(trees))}
/>
</div>
</div>
);
}
Example #5
Source File: index.tsx From datart with Apache License 2.0 | 4 votes |
export function Navbar() {
const { actions } = useMainSlice();
const [profileVisible, setProfileVisible] = useState(false);
const [modifyPasswordVisible, setModifyPasswordVisible] = useState(false);
const dispatch = useDispatch();
const history = useHistory();
const { i18n } = useTranslation();
const systemInfo = useSelector(selectSystemInfo);
const orgId = useSelector(selectOrgId);
const currentOrganization = useSelector(selectCurrentOrganization);
const loggedInUser = useSelector(selectLoggedInUser);
const organizationListLoading = useSelector(selectOrganizationListLoading);
const downloadPolling = useSelector(selectDownloadPolling);
const themeKey = useSelector(selectThemeKey);
const matchModules = useRouteMatch<{ moduleName: string }>(
'/organizations/:orgId/:moduleName',
);
const t = useI18NPrefix('main');
const brandClick = useCallback(() => {
history.push('/');
}, [history]);
const hideProfile = useCallback(() => {
setProfileVisible(false);
}, []);
const hideModifyPassword = useCallback(() => {
setModifyPasswordVisible(false);
}, []);
const organizationListVisibleChange = useCallback(
visible => {
if (visible && !organizationListLoading) {
dispatch(getOrganizations());
}
},
[dispatch, organizationListLoading],
);
const subNavs = useMemo(
() => [
{
name: 'variables',
title: t('subNavs.variables.title'),
icon: <FunctionOutlined />,
module: ResourceTypes.Manager,
},
{
name: 'orgSettings',
title: t('subNavs.orgSettings.title'),
icon: <SettingOutlined />,
module: ResourceTypes.Manager,
},
],
[t],
);
const navs = useMemo(
() => [
{
name: 'vizs',
title: t('nav.vizs'),
icon: <i className="iconfont icon-xietongzhihuidaping" />,
module: ResourceTypes.Viz,
},
{
name: 'views',
title: t('nav.views'),
icon: <i className="iconfont icon-24gf-table" />,
module: ResourceTypes.View,
},
{
name: 'sources',
title: t('nav.sources'),
icon: <i className="iconfont icon-shujukupeizhi" />,
module: ResourceTypes.Source,
},
{
name: 'schedules',
title: t('nav.schedules'),
icon: <i className="iconfont icon-fasongyoujian" />,
module: ResourceTypes.Schedule,
},
{
name: 'members',
title: t('nav.members'),
icon: <i className="iconfont icon-users1" />,
isActive: (_, location) =>
!!location.pathname.match(
/\/organizations\/[\w]{32}\/(members|roles)/,
),
module: ResourceTypes.User,
},
{
name: 'permissions',
title: t('nav.permissions'),
icon: <SafetyCertificateFilled />,
module: ResourceTypes.Manager,
},
{
name: 'toSub',
title: t('nav.settings'),
icon: <SettingFilled />,
isActive: (_, location) => {
const reg = new RegExp(
`\\/organizations\\/[\\w]{32}\\/(${subNavs
.map(({ name }) => name)
.join('|')})`,
);
return !!location.pathname.match(reg);
},
module: ResourceTypes.Manager,
},
],
[subNavs, t],
);
const showSubNav = useMemo(
() => subNavs.some(({ name }) => name === matchModules?.params.moduleName),
[matchModules?.params.moduleName, subNavs],
);
const handleChangeThemeFn = useCallback(
(theme: ThemeKeyType) => {
if (themeKey !== theme) {
dispatch(themeSlice.actions.changeTheme(theme));
changeAntdTheme(theme);
saveTheme(theme);
}
},
[dispatch, themeKey],
);
const userMenuSelect = useCallback(
({ key }) => {
switch (key) {
case 'profile':
setProfileVisible(true);
break;
case 'logout':
dispatch(
logout(() => {
history.replace('/');
}),
);
break;
case 'password':
setModifyPasswordVisible(true);
break;
case 'zh':
case 'en':
if (i18n.language !== key) {
changeLang(key);
}
break;
case 'dark':
case 'light':
handleChangeThemeFn(key);
break;
default:
break;
}
},
[dispatch, history, i18n, handleChangeThemeFn],
);
const onSetPolling = useCallback(
(polling: boolean) => {
dispatch(actions.setDownloadPolling(polling));
},
[dispatch, actions],
);
return (
<>
<MainNav>
<Brand onClick={brandClick}>
<img src={logo} alt="logo" />
</Brand>
<Nav>
{navs.map(({ name, title, icon, isActive, module }) => {
return name !== 'toSub' || subNavs.length > 0 ? (
<Access
key={name}
type="module"
module={module}
level={PermissionLevels.Enable}
>
<Tooltip title={title} placement="right">
<NavItem
to={`/organizations/${orgId}/${
name === 'toSub' ? subNavs[0].name : name
}`}
activeClassName="active"
{...(isActive && { isActive })}
>
{icon}
</NavItem>
</Tooltip>
</Access>
) : null;
})}
</Nav>
<Toolbar>
<DownloadListPopup
polling={downloadPolling}
setPolling={onSetPolling}
onLoadTasks={loadTasks}
onDownloadFile={item => {
if (item.id) {
downloadFile(item.id).then(() => {
dispatch(actions.setDownloadPolling(true));
});
}
}}
/>
{systemInfo?.tenantManagementMode ===
TenantManagementMode.Platform && (
<Popup
content={<OrganizationList />}
trigger={['click']}
placement="rightBottom"
onVisibleChange={organizationListVisibleChange}
>
<li>
<Tooltip title={t('nav.organization.title')} placement="right">
<Avatar
src={`${BASE_RESOURCE_URL}${currentOrganization?.avatar}`}
>
<BankFilled />
</Avatar>
</Tooltip>
</li>
</Popup>
)}
<Popup
content={
<Menu
prefixCls="ant-dropdown-menu"
selectable={false}
onClick={userMenuSelect}
>
<MenuListItem
key="language"
prefix={<GlobalOutlined className="icon" />}
title={<p>{t('nav.account.switchLanguage.title')}</p>}
sub
>
<MenuListItem key="zh">中文</MenuListItem>
<MenuListItem key="en">English</MenuListItem>
</MenuListItem>
<MenuListItem
key="theme"
prefix={<SkinOutlined className="icon" />}
title={<p>{t('nav.account.switchTheme.title')}</p>}
sub
>
<MenuListItem key="light" prefix={<ThemeBadge />}>
{t('nav.account.switchTheme.light')}
</MenuListItem>
<MenuListItem
key="dark"
prefix={<ThemeBadge background={BLACK} />}
>
{t('nav.account.switchTheme.dark')}
</MenuListItem>
</MenuListItem>
<Menu.Divider />
<MenuListItem
key="profile"
prefix={<ProfileOutlined className="icon" />}
>
<p>{t('nav.account.profile.title')}</p>
</MenuListItem>
<MenuListItem
key="password"
prefix={<FormOutlined className="icon" />}
>
<p>{t('nav.account.changePassword.title')}</p>
</MenuListItem>
<MenuListItem
key="logout"
prefix={<ExportOutlined className="icon" />}
>
<p>{t('nav.account.logout.title')}</p>
</MenuListItem>
</Menu>
}
trigger={['click']}
placement="rightBottom"
>
<li>
<Avatar src={`${BASE_RESOURCE_URL}${loggedInUser?.avatar}`}>
<UserOutlined />
</Avatar>
</li>
</Popup>
</Toolbar>
<Profile visible={profileVisible} onCancel={hideProfile} />
<ModifyPassword
visible={modifyPasswordVisible}
onCancel={hideModifyPassword}
/>
</MainNav>
{showSubNav && (
<SubNav>
<List
dataSource={subNavs}
renderItem={({ name, title, icon }) => (
<SubNavTitle
key={name}
to={`/organizations/${orgId}/${name}`}
activeClassName="active"
>
{cloneElement(icon, { className: 'prefix' })}
<h4>{title}</h4>
</SubNavTitle>
)}
/>
</SubNav>
)}
</>
);
}
Example #6
Source File: HTTPFuzzerPage.tsx From yakit with GNU Affero General Public License v3.0 | 4 votes |
HTTPFuzzerPage: React.FC<HTTPFuzzerPageProp> = (props) => {
// params
const [isHttps, setIsHttps, getIsHttps] = useGetState<boolean>(props.fuzzerParams?.isHttps || props.isHttps || false)
const [noFixContentLength, setNoFixContentLength] = useState(false)
const [request, setRequest, getRequest] = useGetState(props.fuzzerParams?.request || props.request || defaultPostTemplate)
const [concurrent, setConcurrent] = useState(props.fuzzerParams?.concurrent || 20)
const [forceFuzz, setForceFuzz] = useState<boolean>(props.fuzzerParams?.forceFuzz || true)
const [timeout, setParamTimeout] = useState(props.fuzzerParams?.timeout || 10.0)
const [proxy, setProxy] = useState(props.fuzzerParams?.proxy || "")
const [actualHost, setActualHost] = useState(props.fuzzerParams?.actualHost || "")
const [advancedConfig, setAdvancedConfig] = useState(false)
const [redirectedResponse, setRedirectedResponse] = useState<FuzzerResponse>()
const [historyTask, setHistoryTask] = useState<HistoryHTTPFuzzerTask>();
const [hotPatchCode, setHotPatchCode] = useState<string>("");
// filter
const [_, setFilter, getFilter] = useGetState<FuzzResponseFilter>({
Keywords: [],
MaxBodySize: 0,
MinBodySize: 0,
Regexps: [],
StatusCode: []
});
const [droppedCount, setDroppedCount] = useState(0);
// state
const [loading, setLoading] = useState(false)
const [content, setContent] = useState<FuzzerResponse[]>([])
const [reqEditor, setReqEditor] = useState<IMonacoEditor>()
const [fuzzToken, setFuzzToken] = useState("")
const [search, setSearch] = useState("")
const [targetUrl, setTargetUrl] = useState("")
const [refreshTrigger, setRefreshTrigger] = useState(false)
const refreshRequest = () => {
setRefreshTrigger(!refreshTrigger)
}
// history
const [history, setHistory] = useState<string[]>([])
const [currentHistoryIndex, setCurrentHistoryIndex] = useState<number>()
const [urlPacketShow, setUrlPacketShow] = useState<boolean>(false)
// filter
const [keyword, setKeyword] = useState<string>("")
const [filterContent, setFilterContent] = useState<FuzzerResponse[]>([])
const [timer, setTimer] = useState<any>()
useEffect(() => {
getValue(WEB_FUZZ_HOTPATCH_CODE).then((data: any) => {
if (!data) {
return
}
setHotPatchCode(`${data}`)
})
}, [])
// 定时器
const sendTimer = useRef<any>(null)
const withdrawRequest = useMemoizedFn(() => {
const targetIndex = history.indexOf(request) - 1
if (targetIndex >= 0) {
setRequest(history[targetIndex])
setCurrentHistoryIndex(targetIndex)
}
})
const forwardRequest = useMemoizedFn(() => {
const targetIndex = history.indexOf(request) + 1
if (targetIndex < history.length) {
setCurrentHistoryIndex(targetIndex)
setRequest(history[targetIndex])
}
})
const sendToFuzzer = useMemoizedFn((isHttps: boolean, request: string) => {
ipcRenderer.invoke("send-to-tab", {
type: "fuzzer",
data: {isHttps: isHttps, request: request}
})
})
const sendToPlugin = useMemoizedFn((request: Uint8Array, isHTTPS: boolean, response?: Uint8Array) => {
let m = showDrawer({
width: "80%",
content: <HackerPlugin request={request} isHTTPS={isHTTPS} response={response}></HackerPlugin>
})
})
// 从历史记录中恢复
useEffect(() => {
if (!historyTask) {
return
}
setRequest(historyTask.Request)
setIsHttps(historyTask.IsHTTPS)
setProxy(historyTask.Proxy)
refreshRequest()
}, [historyTask])
useEffect(() => {
// 缓存全局参数
getValue(WEB_FUZZ_PROXY).then(e => {
if (!e) {
return
}
setProxy(`${e}`)
})
}, [])
useEffect(() => {
if (currentHistoryIndex === undefined) {
return
}
refreshRequest()
}, [currentHistoryIndex])
useEffect(() => {
setIsHttps(!!props.isHttps)
if (props.request) {
setRequest(props.request)
setContent([])
}
}, [props.isHttps, props.request])
const loadHistory = useMemoizedFn((id: number) => {
setLoading(true)
setHistory([])
ipcRenderer.invoke(
"HTTPFuzzer",
{HistoryWebFuzzerId: id}, fuzzToken
).then(() => {
ipcRenderer.invoke("GetHistoryHTTPFuzzerTask", {Id: id}).then((data: { OriginRequest: HistoryHTTPFuzzerTask }) => {
setHistoryTask(data.OriginRequest)
})
})
})
const submitToHTTPFuzzer = useMemoizedFn(() => {
// 清楚历史任务的标记
setHistoryTask(undefined);
saveValue(WEB_FUZZ_PROXY, proxy)
setLoading(true)
if (history.includes(request)) {
history.splice(history.indexOf(request), 1)
}
history.push(request)
setHistory([...history])
setDroppedCount(0)
ipcRenderer.invoke(
"HTTPFuzzer",
{
Request: request,
ForceFuzz: forceFuzz,
IsHTTPS: isHttps,
Concurrent: concurrent,
PerRequestTimeoutSeconds: timeout,
NoFixContentLength: noFixContentLength,
Proxy: proxy,
ActualAddr: actualHost,
HotPatchCode: hotPatchCode,
Filter: getFilter(),
},
fuzzToken
)
})
const cancelCurrentHTTPFuzzer = useMemoizedFn(() => {
ipcRenderer.invoke("cancel-HTTPFuzzer", fuzzToken)
})
useEffect(() => {
const token = randomString(60)
setFuzzToken(token)
const dataToken = `${token}-data`
const errToken = `${token}-error`
const endToken = `${token}-end`
ipcRenderer.on(errToken, (e, details) => {
notification["error"]({
message: `提交模糊测试请求失败 ${details}`,
placement: "bottomRight"
})
})
let buffer: FuzzerResponse[] = []
let droppedCount = 0;
let count: number = 0
const updateData = () => {
if (buffer.length <= 0) {
return
}
if (JSON.stringify(buffer) !== JSON.stringify(content)) setContent([...buffer])
}
ipcRenderer.on(dataToken, (e: any, data: any) => {
if (data["MatchedByFilter"] !== true && !filterIsEmpty(getFilter())) {
// 不匹配的
droppedCount++
setDroppedCount(droppedCount)
return
}
// const response = new Buffer(data.ResponseRaw).toString(fixEncoding(data.GuessResponseEncoding))
buffer.push({
StatusCode: data.StatusCode,
Ok: data.Ok,
Reason: data.Reason,
Method: data.Method,
Host: data.Host,
ContentType: data.ContentType,
Headers: (data.Headers || []).map((i: any) => {
return {Header: i.Header, Value: i.Value}
}),
DurationMs: data.DurationMs,
BodyLength: data.BodyLength,
UUID: data.UUID,
Timestamp: data.Timestamp,
ResponseRaw: data.ResponseRaw,
RequestRaw: data.RequestRaw,
Payloads: data.Payloads,
IsHTTPS: data.IsHTTPS,
Count: count,
BodySimilarity: data.BodySimilarity,
HeaderSimilarity: data.HeaderSimilarity,
} as FuzzerResponse)
count++
// setContent([...buffer])
})
ipcRenderer.on(endToken, () => {
updateData()
buffer = []
count = 0
droppedCount = 0
setLoading(false)
})
const updateDataId = setInterval(() => {
updateData()
}, 200)
return () => {
ipcRenderer.invoke("cancel-HTTPFuzzer", token)
clearInterval(updateDataId)
ipcRenderer.removeAllListeners(errToken)
ipcRenderer.removeAllListeners(dataToken)
ipcRenderer.removeAllListeners(endToken)
}
}, [])
const searchContent = (keyword: string) => {
if (timer) {
clearTimeout(timer)
setTimer(null)
}
setTimer(
setTimeout(() => {
try {
const filters = content.filter((item) => {
return Buffer.from(item.ResponseRaw).toString("utf8").match(new RegExp(keyword, "g"))
})
setFilterContent(filters)
} catch (error) {
}
}, 500)
)
}
const downloadContent = useMemoizedFn(() => {
if (!keyword) {
failed('请先输入需要搜索的关键词')
return
}
const strs = []
try {
const reg = new RegExp(keyword)
for (let info of filterContent) {
let str = Buffer.from(info.ResponseRaw).toString('utf8')
let temp: any
while ((temp = reg.exec(str)) !== null) {
// @ts-ignore
if (temp[1]) {
// @ts-ignore
strs.push(temp[1])
str = str.substring(temp['index'] + 1)
reg.lastIndex = 0
} else {
break
}
}
}
} catch (error) {
failed("正则有问题,请检查后重新输入")
return
}
if (strs.length === 0) {
failed('未捕获到关键词信息')
return
}
ipcRenderer.invoke("show-save-dialog", 'fuzzer列表命中内容.txt').then((res) => {
if (res.canceled) return
ipcRenderer
.invoke("write-file", {
route: res.filePath,
data: strs.join('\n\r')
})
.then(() => {
success('下载完成')
ipcRenderer.invoke("open-specified-file", res.filePath)
})
})
})
useEffect(() => {
if (!!keyword) {
searchContent(keyword)
} else {
setFilterContent([])
}
}, [keyword])
useEffect(() => {
if (keyword && content.length !== 0) {
const filters = content.filter(item => {
return Buffer.from(item.ResponseRaw).toString("utf8").match(new RegExp(keyword, 'g'))
})
setFilterContent(filters)
}
}, [content])
const onlyOneResponse = !loading && (content || []).length === 1
const filtredResponses =
search === ""
? content || []
: (content || []).filter((i) => {
return Buffer.from(i.ResponseRaw).toString().includes(search)
})
const successResults = filtredResponses.filter((i) => i.Ok)
const failedResults = filtredResponses.filter((i) => !i.Ok)
const sendFuzzerSettingInfo = useMemoizedFn(() => {
const info: fuzzerInfoProp = {
time: new Date().getTime().toString(),
isHttps: isHttps,
forceFuzz: forceFuzz,
concurrent: concurrent,
proxy: proxy,
actualHost: actualHost,
timeout: timeout,
request: request
}
if (sendTimer.current) {
clearTimeout(sendTimer.current)
sendTimer.current = null
}
sendTimer.current = setTimeout(() => {
ipcRenderer.invoke('send-fuzzer-setting-data', {key: props.order || "", param: JSON.stringify(info)})
}, 1000);
})
useEffect(() => {
sendFuzzerSettingInfo()
}, [isHttps, forceFuzz, concurrent, proxy, actualHost, timeout, request])
const responseViewer = useMemoizedFn((rsp: FuzzerResponse) => {
return (
<HTTPPacketEditor
system={props.system}
originValue={rsp.ResponseRaw}
bordered={true}
hideSearch={true}
emptyOr={
!rsp?.Ok && (
<Result
status={"error"}
title={"请求失败"}
// no such host
subTitle={(() => {
const reason = content[0]!.Reason
if (reason.includes("tcp: i/o timeout")) {
return "网络超时"
}
if (reason.includes("no such host")) {
return "DNS 错误或主机错误"
}
return undefined
})()}
>
<>详细原因:{rsp.Reason}</>
</Result>
)
}
readOnly={true}
extra={
(
<Space>
{loading && <Spin size={"small"} spinning={loading}/>}
{onlyOneResponse ? (
<Space>
{content[0].IsHTTPS && <Tag>{content[0].IsHTTPS ? "https" : ""}</Tag>}
<Tag>{content[0].DurationMs}ms</Tag>
<Space key='single'>
<Button
size={"small"}
onClick={() => {
analyzeFuzzerResponse(
rsp,
(bool, r) => {
// setRequest(r)
// refreshRequest()
}
)
}}
type={"primary"}
icon={<ProfileOutlined/>}
>
详情
</Button>
<Button
type={"primary"}
size={"small"}
onClick={() => {
setContent([])
}}
danger={true}
icon={<DeleteOutlined/>}
/>
</Space>
</Space>
) : (
<Space key='list'>
<Tag color={"green"}>成功:{successResults.length}</Tag>
<Input
size={"small"}
value={search}
onChange={(e) => {
setSearch(e.target.value)
}}
/>
{/*<Tag>当前请求结果数[{(content || []).length}]</Tag>*/}
<Button
size={"small"}
onClick={() => {
setContent([])
}}
>
清除数据
</Button>
</Space>
)}
</Space>
)
}
/>
)
})
const hotPatchTrigger = useMemoizedFn(() => {
let m = showModal({
title: "调试 / 插入热加载代码",
width: "60%",
content: (
<div>
<HTTPFuzzerHotPatch initialHotPatchCode={hotPatchCode || ""} onInsert={tag => {
if (reqEditor) monacoEditorWrite(reqEditor, tag);
m.destroy()
}} onSaveCode={code => {
setHotPatchCode(code)
saveValue(WEB_FUZZ_HOTPATCH_CODE, code)
}}/>
</div>
)
})
})
return (
<div style={{height: "100%", width: "100%", display: "flex", flexDirection: "column", overflow: "hidden"}}>
<Row gutter={8} style={{marginBottom: 8}}>
<Col span={24} style={{textAlign: "left", marginTop: 4}}>
<Space>
{loading ? (
<Button
style={{width: 150}}
onClick={() => {
cancelCurrentHTTPFuzzer()
}}
// size={"small"}
danger={true}
type={"primary"}
>
强制停止
</Button>
) : (
<Button
style={{width: 150}}
onClick={() => {
setContent([])
setRedirectedResponse(undefined)
sendFuzzerSettingInfo()
submitToHTTPFuzzer()
}}
// size={"small"}
type={"primary"}
>
发送数据包
</Button>
)}
<Space>
<Button
onClick={() => {
withdrawRequest()
}}
type={"link"}
icon={<LeftOutlined/>}
/>
<Button
onClick={() => {
forwardRequest()
}}
type={"link"}
icon={<RightOutlined/>}
/>
{history.length > 1 && (
<Dropdown
trigger={["click"]}
overlay={() => {
return (
<Menu>
{history.map((i, index) => {
return (
<Menu.Item
style={{width: 120}}
onClick={() => {
setRequest(i)
setCurrentHistoryIndex(index)
}}
>{`${index}`}</Menu.Item>
)
})}
</Menu>
)
}}
>
<Button size={"small"} type={"link"} onClick={(e) => e.preventDefault()}>
History <DownOutlined/>
</Button>
</Dropdown>
)}
</Space>
<Checkbox defaultChecked={isHttps} value={isHttps} onChange={() => setIsHttps(!isHttps)}>强制
HTTPS</Checkbox>
<SwitchItem
label={"高级配置"}
formItemStyle={{marginBottom: 0}}
value={advancedConfig}
setValue={setAdvancedConfig}
size={"small"}
/>
{droppedCount > 0 && <Tag color={"red"}>已丢弃[{droppedCount}]个响应</Tag>}
{onlyOneResponse && content[0].Ok && (
<Form.Item style={{marginBottom: 0}}>
<Button
onClick={() => {
setLoading(true)
ipcRenderer
.invoke("RedirectRequest", {
Request: request,
Response: new Buffer(content[0].ResponseRaw).toString("utf8"),
IsHttps: isHttps,
PerRequestTimeoutSeconds: timeout,
NoFixContentLength: noFixContentLength,
Proxy: proxy
})
.then((rsp: FuzzerResponse) => {
setRedirectedResponse(rsp)
})
.catch((e) => {
failed(`"ERROR in: ${e}"`)
})
.finally(() => {
setTimeout(() => setLoading(false), 300)
})
}}
>
跟随重定向
</Button>
</Form.Item>
)}
{loading && (
<Space>
<Spin size={"small"}/>
<div style={{color: "#3a8be3"}}>sending packets</div>
</Space>
)}
{proxy && <Tag>代理:{proxy}</Tag>}
{/*<Popover*/}
{/* trigger={"click"}*/}
{/* content={*/}
{/* }*/}
{/*>*/}
{/* <Button type={"link"} size={"small"}>*/}
{/* 配置请求包*/}
{/* </Button>*/}
{/*</Popover>*/}
{actualHost !== "" && <Tag color={"red"}>请求 Host:{actualHost}</Tag>}
</Space>
</Col>
{/*<Col span={12} style={{textAlign: "left"}}>*/}
{/*</Col>*/}
</Row>
{advancedConfig && (
<Row style={{marginBottom: 8}} gutter={8}>
<Col span={16}>
{/*高级配置*/}
<Card bordered={true} size={"small"} bodyStyle={{height: 106}}>
<Spin style={{width: "100%"}} spinning={!reqEditor}>
<Form
onSubmitCapture={(e) => e.preventDefault()}
// layout={"horizontal"}
size={"small"}
// labelCol={{span: 8}}
// wrapperCol={{span: 16}}
>
<Row gutter={8}>
<Col span={12} xl={8}>
<Form.Item
label={<OneLine width={68}>Intruder</OneLine>}
style={{marginBottom: 4}}
>
<Button
style={{backgroundColor: "#08a701"}}
size={"small"}
type={"primary"}
onClick={() => {
const m = showModal({
width: "70%",
content: (
<>
<StringFuzzer
advanced={true}
disableBasicMode={true}
insertCallback={(template: string) => {
if (!template) {
Modal.warn({
title: "Payload 为空 / Fuzz 模版为空"
})
} else {
if (reqEditor && template) {
reqEditor.trigger(
"keyboard",
"type",
{
text: template
}
)
} else {
Modal.error({
title: "BUG: 编辑器失效"
})
}
m.destroy()
}
}}
/>
</>
)
})
}}
>
插入 yak.fuzz 语法
</Button>
</Form.Item>
</Col>
<Col span={12} xl={8}>
<SwitchItem
label={<OneLine width={68}>渲染 fuzz</OneLine>}
setValue={(e) => {
if (!e) {
Modal.confirm({
title: "确认关闭 Fuzz 功能吗?关闭之后,所有的 Fuzz 标签将会失效",
onOk: () => {
setForceFuzz(e)
}
})
return
}
setForceFuzz(e)
}}
size={"small"}
value={forceFuzz}
formItemStyle={{marginBottom: 4}}
/>
</Col>
<Col span={12} xl={8}>
<InputInteger
label={<OneLine width={68}>并发线程</OneLine>}
size={"small"}
setValue={(e) => {
setConcurrent(e)
}}
formItemStyle={{marginBottom: 4}} // width={40}
width={50}
value={concurrent}
/>
</Col>
<Col span={12} xl={8}>
<SwitchItem
label={<OneLine width={68}>HTTPS</OneLine>}
setValue={(e) => {
setIsHttps(e)
}}
size={"small"}
value={isHttps}
formItemStyle={{marginBottom: 4}}
/>
</Col>
<Col span={12} xl={8}>
<SwitchItem
label={<OneLine width={70}>
<Tooltip title={"不修复 Content-Length: 常用发送多个数据包"}>
不修复长度
</Tooltip>
</OneLine>}
setValue={(e) => {
setNoFixContentLength(e)
}}
size={"small"}
value={noFixContentLength}
formItemStyle={{marginBottom: 4}}
/>
</Col>
<Col span={12} xl={8}>
<ItemSelects
item={{
style: {marginBottom: 4},
label: <OneLine width={68}>设置代理</OneLine>,
}}
select={{
style: {width: "100%"},
allowClear: true,
autoClearSearchValue: true,
maxTagTextLength: 8,
mode: "tags",
data: [
{text: "http://127.0.0.1:7890", value: "http://127.0.0.1:7890"},
{text: "http://127.0.0.1:8080", value: "http://127.0.0.1:8080"},
{text: "http://127.0.0.1:8082", value: "http://127.0.0.1:8082"}
],
value: proxy ? proxy.split(",") : [],
setValue: (value) => setProxy(value.join(",")),
maxTagCount: "responsive",
}}
></ItemSelects>
{/* <ManyMultiSelectForString
formItemStyle={{marginBottom: 4}}
label={<OneLine width={68}>设置代理</OneLine>}
data={[
"http://127.0.0.1:7890",
"http://127.0.0.1:8080",
"http://127.0.0.1:8082"
].map((i) => {
return {label: i, value: i}
})}
mode={"tags"}
defaultSep={","}
value={proxy}
setValue={(r) => {
setProxy(r.split(",").join(","))
}}
/> */}
</Col>
<Col span={12} xl={8}>
<InputItem
extraFormItemProps={{
style: {marginBottom: 0}
}}
label={<OneLine width={68}>请求 Host</OneLine>}
setValue={setActualHost}
value={actualHost}
/>
</Col>
<Col span={12} xl={8}>
<InputFloat
formItemStyle={{marginBottom: 4}}
size={"small"}
label={<OneLine width={68}>超时时间</OneLine>}
setValue={setParamTimeout}
value={timeout}
/>
</Col>
</Row>
</Form>
</Spin>
</Card>
</Col>
<Col span={8}>
<AutoCard title={<Tooltip title={"通过过滤匹配,丢弃无用数据包,保证界面性能!"}>
设置过滤器
</Tooltip>}
bordered={false} size={"small"} bodyStyle={{paddingTop: 4}}
style={{marginTop: 0, paddingTop: 0}}
>
<Form size={"small"} onSubmitCapture={e => e.preventDefault()}>
<Row gutter={20}>
<Col span={12}>
<InputItem
label={"状态码"} placeholder={"200,300-399"}
disable={loading}
value={getFilter().StatusCode.join(",")}
setValue={e => {
setFilter({...getFilter(), StatusCode: e.split(",").filter(i => !!i)})
}}
extraFormItemProps={{style: {marginBottom: 0}}}
/>
</Col>
<Col span={12}>
<InputItem
label={"关键字"} placeholder={"Login,登录成功"}
value={getFilter().Keywords.join(",")}
disable={loading}
setValue={e => {
setFilter({...getFilter(), Keywords: e.split(",").filter(i => !!i)})
}}
extraFormItemProps={{style: {marginBottom: 0}}}
/>
</Col>
<Col span={12}>
<InputItem
label={"正则"} placeholder={`Welcome\\s+\\w+!`}
value={getFilter().Regexps.join(",")}
disable={loading}
setValue={e => {
setFilter({...getFilter(), Regexps: e.split(",").filter(i => !!i)})
}}
extraFormItemProps={{style: {marginBottom: 0, marginTop: 2}}}
/>
</Col>
</Row>
</Form>
</AutoCard>
</Col>
</Row>
)}
{/*<Divider style={{marginTop: 6, marginBottom: 8, paddingTop: 0}}/>*/}
<ResizeBox
firstMinSize={350} secondMinSize={360}
style={{overflow: "hidden"}}
firstNode={<HTTPPacketEditor
system={props.system}
refreshTrigger={refreshTrigger}
hideSearch={true}
bordered={true}
originValue={new Buffer(request)}
actions={[
{
id: "packet-from-url",
label: "URL转数据包",
contextMenuGroupId: "1_urlPacket",
run: () => {
setUrlPacketShow(true)
}
},
{
id: "copy-as-url",
label: "复制为 URL",
contextMenuGroupId: "1_urlPacket",
run: () => {
copyAsUrl({Request: getRequest(), IsHTTPS: getIsHttps()})
}
},
{
id: "insert-intruder-tag",
label: "插入模糊测试字典标签",
contextMenuGroupId: "1_urlPacket",
run: (editor) => {
showDictsAndSelect(i => {
monacoEditorWrite(editor, i, editor.getSelection())
})
}
},
{
id: "insert-hotpatch-tag",
label: "插入热加载标签",
contextMenuGroupId: "1_urlPacket",
run: (editor) => {
hotPatchTrigger()
}
},
]}
onEditor={setReqEditor}
onChange={(i) => setRequest(new Buffer(i).toString("utf8"))}
extra={
<Space size={2}>
<Button
style={{marginRight: 1}}
size={"small"} type={"primary"}
onClick={() => {
hotPatchTrigger()
}}
>热加载标签</Button>
<Popover
trigger={"click"}
title={"从 URL 加载数据包"}
content={
<div style={{width: 400}}>
<Form
layout={"vertical"}
onSubmitCapture={(e) => {
e.preventDefault()
ipcRenderer
.invoke("Codec", {
Type: "packet-from-url",
Text: targetUrl
})
.then((e) => {
if (e?.Result) {
setRequest(e.Result)
refreshRequest()
}
})
.finally(() => {
})
}}
size={"small"}
>
<InputItem
label={"从 URL 构造请求"}
value={targetUrl}
setValue={setTargetUrl}
extraFormItemProps={{style: {marginBottom: 8}}}
></InputItem>
<Form.Item style={{marginBottom: 8}}>
<Button type={"primary"} htmlType={"submit"}>
构造请求
</Button>
</Form.Item>
</Form>
</div>
}
>
<Button size={"small"} type={"primary"}>
URL
</Button>
</Popover>
<Popover
trigger={"click"}
placement={"bottom"}
destroyTooltipOnHide={true}
content={
<div style={{width: 400}}>
<HTTPFuzzerHistorySelector onSelect={e => {
loadHistory(e)
}}/>
</div>
}
>
<Button size={"small"} type={"primary"} icon={<HistoryOutlined/>}>
历史
</Button>
</Popover>
</Space>
}
/>}
secondNode={<AutoSpin spinning={false}>
{onlyOneResponse ? (
<>{redirectedResponse ? responseViewer(redirectedResponse) : responseViewer(content[0])}</>
) : (
<>
{(content || []).length > 0 ? (
<HTTPFuzzerResultsCard
onSendToWebFuzzer={sendToFuzzer}
sendToPlugin={sendToPlugin}
setRequest={(r) => {
setRequest(r)
refreshRequest()
}}
extra={
<div>
<Input
value={keyword}
style={{maxWidth: 200}}
allowClear
placeholder="输入字符串或正则表达式"
onChange={e => setKeyword(e.target.value)}
addonAfter={
<DownloadOutlined style={{cursor: "pointer"}}
onClick={downloadContent}/>
}></Input>
</div>
}
failedResponses={failedResults}
successResponses={filterContent.length !== 0 ? filterContent : keyword ? [] : successResults}
/>
) : (
<Result
status={"info"}
title={"请在左边编辑并发送一个 HTTP 请求/模糊测试"}
subTitle={
"本栏结果针对模糊测试的多个 HTTP 请求结果展示做了优化,可以自动识别单个/多个请求的展示"
}
/>
)}
</>
)}
</AutoSpin>}/>
<Modal
visible={urlPacketShow}
title='从 URL 加载数据包'
onCancel={() => setUrlPacketShow(false)}
footer={null}
>
<Form
layout={"vertical"}
onSubmitCapture={(e) => {
e.preventDefault()
ipcRenderer
.invoke("Codec", {
Type: "packet-from-url",
Text: targetUrl
})
.then((e) => {
if (e?.Result) {
setRequest(e.Result)
refreshRequest()
setUrlPacketShow(false)
}
})
.finally(() => {
})
}}
size={"small"}
>
<InputItem
label={"从 URL 构造请求"}
value={targetUrl}
setValue={setTargetUrl}
extraFormItemProps={{style: {marginBottom: 8}}}
></InputItem>
<Form.Item style={{marginBottom: 8}}>
<Button type={"primary"} htmlType={"submit"}>
构造请求
</Button>
</Form.Item>
</Form>
</Modal>
</div>
)
}