Expose user allowlist and blocklist sender commands - #2261
Conversation
Refresh the generated Mail skill metadata for allow and block sender resources. Add focused contract tests for generated commands, scopes, request shapes, and dry-run routing.
📝 WalkthroughWalkthroughAdded generated tests for mail sender allow-list and block-list resources. Expanded the mail skill with recipient discovery, sending safeguards, HTML linting, templates, shortcuts, API documentation, and permissions. ChangesMail sender resource tests
Mail skill guidance
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@f3eb37181b26b0cb1bc446d919316019567c9286🧩 Skill updatenpx skills add sysuljx/cli#feat/c60b367 -y -g |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/service/mail_sender_generated_test.go`:
- Around line 232-260: Update the dry-run assertions in the contract test around
the envelope API call to project list parameters, create bodies, and remove
bodies into distinct typed structs instead of inspecting generic maps. Assert
the exact expected create sender and sender_type values, and the exact remove
sender list, while preserving the existing list keyword and page_size checks.
- Around line 196-204: The error-path tests must assert typed metadata in both
affected locations: in cmd/service/mail_sender_generated_test.go lines 196-204,
retain errors.As and validationErr.Param == "user_mailbox_id", then assert
Category and Subtype via errs.ProblemOf(err) without using it for Param; in
lines 288-294, assert the permission error’s Category and Subtype via
errs.ProblemOf(err) before checking MissingScopes.
- Line 162: Update cmd/service/mail_sender_generated_test.go at lines 162-162
and 310-310 to use cmdutil.TestFactory(t, config) instead of raw
&cmdutil.Factory{} values. At lines 188-188 and 214-214, call
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) before creating the factory,
and ensure all affected tests use isolated TestFactory setup.
In `@skills/lark-mail/SKILL.md`:
- Line 4: Update the skill description trigger list and the sender-list
documentation near the API method section to cover allowlist and blocklist
operations in Chinese and English. Add concrete user-facing examples for
listing, getting, setting, and deleting entries for both sender-list resources,
including mailbox identity, sender type, pagination, and required confirmation
behavior; retain the existing API method references.
- Around line 115-117: Update the workflow around the `user_mailboxes profile`
step so the relevant `-h` command runs first, or explicitly state that the
numbered workflow begins after the mandatory initial help check. Keep the
existing `profile` operation and first-use ordering consistent with the
documented requirement.
- Around line 299-309: Update the example command’s --event-start and
--event-end values to use a clearly future calendar date relative to August 10,
2026, while preserving the one-hour meeting duration and timezone.
- Around line 207-216: Update the mail write examples for public-mailbox and
alias sends, cancel_scheduled_send, and all +draft-* shortcuts to include the
required --as user option, consistent with the guidance on lines 88-91. If these
shortcuts intentionally enforce user identity instead, document that behavior
explicitly.
- Around line 555-561: The permission table entries for
user_mailbox.allow_senders.list and user_mailbox.blocked_senders.list currently
omit a required scope. Update both rows to document
mail:user_mailbox.message:readonly and mail:user_mailbox.message:modify,
matching the generated contract and preserving the existing endpoint
descriptions.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 94d46c28-ed0b-4e6f-8769-1fabdf500eaa
📒 Files selected for processing (2)
cmd/service/mail_sender_generated_test.goskills/lark-mail/SKILL.md
| func TestGeneratedMailUserSenderCommandsHelpAndRequiredMailbox(t *testing.T) { | ||
| service := generatedMailService(t) | ||
| root := &cobra.Command{Use: "lark-cli"} | ||
| registerService(root, service, &cmdutil.Factory{}) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Initialize and isolate each test factory.
Raw factories bypass the standard test fixture setup. The TestFactory calls also lack the required isolated configuration directory.
cmd/service/mail_sender_generated_test.go#L162-L162: Replace&cmdutil.Factory{}with a factory fromcmdutil.TestFactory.cmd/service/mail_sender_generated_test.go#L188-L188: SetLARKSUITE_CLI_CONFIG_DIRtot.TempDir()before creating the factory.cmd/service/mail_sender_generated_test.go#L214-L214: SetLARKSUITE_CLI_CONFIG_DIRtot.TempDir()before creating the factory.cmd/service/mail_sender_generated_test.go#L310-L310: Replace&cmdutil.Factory{}with a factory fromcmdutil.TestFactory.
As per coding guidelines, tests must use cmdutil.TestFactory(t, config) and isolate configuration state with t.Setenv.
📍 Affects 1 file
cmd/service/mail_sender_generated_test.go#L162-L162(this comment)cmd/service/mail_sender_generated_test.go#L188-L188cmd/service/mail_sender_generated_test.go#L214-L214cmd/service/mail_sender_generated_test.go#L310-L310
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cmd/service/mail_sender_generated_test.go` at line 162, Update
cmd/service/mail_sender_generated_test.go at lines 162-162 and 310-310 to use
cmdutil.TestFactory(t, config) instead of raw &cmdutil.Factory{} values. At
lines 188-188 and 214-214, call t.Setenv("LARKSUITE_CLI_CONFIG_DIR",
t.TempDir()) before creating the factory, and ensure all affected tests use
isolated TestFactory setup.
Source: Coding guidelines
| var validationErr *errs.ValidationError | ||
| if !errors.As(err, &validationErr) { | ||
| t.Fatalf("missing mailbox error = %T %v, want *errs.ValidationError", err, err) | ||
| } | ||
| if validationErr.Param != "user_mailbox_id" || | ||
| !strings.Contains(validationErr.Hint, "--user-mailbox-id") || | ||
| !strings.Contains(validationErr.Hint, "lark-cli schema mail."+contract.resource+"."+contract.method) { | ||
| t.Fatalf("missing mailbox error is not actionable: %+v", validationErr) | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert typed metadata for both error paths.
These tests can pass if the error category or subtype changes. Assert Category and Subtype through errs.ProblemOf(err).
cmd/service/mail_sender_generated_test.go#L196-L204: Also retainerrors.Asand assertvalidationErr.Param == "user_mailbox_id". Do not useerrs.ProblemOfforParam.cmd/service/mail_sender_generated_test.go#L288-L294: Assert the permission error category and subtype before checkingMissingScopes.
As per coding guidelines, error-path tests must assert typed metadata. Based on learnings, errs.ProblemOf does not expose Param.
📍 Affects 1 file
cmd/service/mail_sender_generated_test.go#L196-L204(this comment)cmd/service/mail_sender_generated_test.go#L288-L294
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cmd/service/mail_sender_generated_test.go` around lines 196 - 204, The
error-path tests must assert typed metadata in both affected locations: in
cmd/service/mail_sender_generated_test.go lines 196-204, retain errors.As and
validationErr.Param == "user_mailbox_id", then assert Category and Subtype via
errs.ProblemOf(err) without using it for Param; in lines 288-294, assert the
permission error’s Category and Subtype via errs.ProblemOf(err) before checking
MissingScopes.
Sources: Coding guidelines, Learnings
| var envelope struct { | ||
| OK bool `json:"ok"` | ||
| DryRun bool `json:"dry_run"` | ||
| Data struct { | ||
| API []struct { | ||
| Method string `json:"method"` | ||
| URL string `json:"url"` | ||
| Params map[string]interface{} `json:"params"` | ||
| Body map[string]interface{} `json:"body"` | ||
| } `json:"api"` | ||
| } `json:"data"` | ||
| } | ||
| if err := json.Unmarshal(stdout.Bytes(), &envelope); err != nil { | ||
| t.Fatalf("dry-run output is not JSON: %v\n%s", err, stdout.String()) | ||
| } | ||
| if !envelope.OK || !envelope.DryRun || len(envelope.Data.API) != 1 { | ||
| t.Fatalf("unexpected dry-run envelope: %s", stdout.String()) | ||
| } | ||
| call := envelope.Data.API[0] | ||
| wantURL := "/open-apis/mail/v1/" + strings.Replace(contract.path, "{user_mailbox_id}", "me", 1) | ||
| if call.Method != contract.httpMethod || call.URL != wantURL { | ||
| t.Fatalf("dry-run transport = %s %s, want %s %s", call.Method, call.URL, contract.httpMethod, wantURL) | ||
| } | ||
| if contract.method == "list" { | ||
| if call.Params["keyword"] != "example" || call.Params["page_size"] != float64(20) { | ||
| t.Fatalf("list params = %#v, want keyword and page_size", call.Params) | ||
| } | ||
| } else if _, ok := call.Body[contract.bodyField]; !ok { | ||
| t.Fatalf("write body = %#v, want %q", call.Body, contract.bodyField) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Assert typed create and remove request bodies.
The test only checks that the body contains items or senders. It does not verify the supplied sender values. A regression that drops sender, changes sender_type, or changes the remove list can still pass.
Decode each request shape into a typed struct. Assert the exact create and remove values. Use distinct structs for list parameters, create bodies, and remove bodies.
As per coding guidelines, contract tests must assert changed fields directly, and JSON maps must be projected into typed structures at the boundary.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@cmd/service/mail_sender_generated_test.go` around lines 232 - 260, Update the
dry-run assertions in the contract test around the envelope API call to project
list parameters, create bodies, and remove bodies into distinct typed structs
instead of inspecting generic maps. Assert the exact expected create sender and
sender_type values, and the exact remove sender list, while preserving the
existing list keyword and page_size checks.
Source: Coding guidelines
| name: lark-mail | ||
| version: 1.0.0 | ||
| description: "飞书邮箱:Use when user mentions 起草邮件、写邮件、草稿、发送/回复/转发邮件、查阅邮件、看邮件、搜索邮件、邮件文件夹、邮件标签、邮件联系人、监听新邮件、邮件收信规则等;use for mail/email intent only. Do not use for docs/sheets/calendar/auth setup/pure contact lookup/IM chat tasks." | ||
| description: "飞书邮箱 — draft, compose, send, reply, forward, read, and search emails; manage drafts, folders, labels, contacts, attachments, and mail rules; lint and auto-fix mail HTML for Feishu editor compatibility. Use when user mentions 起草邮件, 写一封邮件, 拟邮件, 草稿, 发通知邮件, 发送邮件, 发邮件, 回复邮件, 转发邮件, 查看邮件, 看邮件, 读邮件, 搜索邮件, 查邮件, 收件箱, 邮件会话, 编辑草稿, 管理草稿, 下载附件, 邮件文件夹, 邮件标签, 邮件联系人, 监听新邮件, 收信规则, 邮件规则, 校验邮件HTML, 检查邮件HTML, 邮件HTML兼容性, lint mail HTML, +lint-html, draft, compose, send email, reply, forward, inbox, mail thread, mail rules." |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Add sender-list triggers and command examples.
The PR adds allowlist and blocklist management, but Line 4 does not include trigger terms for these requests. Lines 551-561 list API methods only. They do not show the promised user-facing list, get, set, and delete operations.
Add Chinese and English trigger phrases and concrete commands for both sender-list resources. Include mailbox identity, sender type, pagination, and confirmation behavior. Otherwise, sender-list requests can miss this skill, and users cannot discover the new commands.
This follows the PR objective to document list, get, set, and delete commands for both sender lists.
Also applies to: 551-561
🧰 Tools
🪛 SkillSpector (2.5.1)
[error] 32: [P1] Instruction Override: This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
Remediation: Remove or rewrite any text that instructs the agent to ignore prompts, override safety rules, or trust unverified content. Ensure skill content cannot be injected to alter agent behavior.
(Prompt Injection (P1))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/lark-mail/SKILL.md` at line 4, Update the skill description trigger
list and the sender-list documentation near the API method section to cover
allowlist and blocklist operations in Chinese and English. Add concrete
user-facing examples for listing, getting, setting, and deleting entries for
both sender-list resources, including mailbox identity, sender type, pagination,
and required confirmation behavior; retain the existing API method references.
| ### CRITICAL — 首次使用任何命令前先查 `-h` | ||
|
|
||
| - 收件人地址搜索:搜索用户邮箱地址、群邮箱地址、邮件组地址,提供给用户确认。ref: [lark-mail-recipient-search](references/lark-mail-recipient-search.md) | ||
| - 使用公共邮箱发信、使用邮箱别名发信:通过 `--mailbox` 指定邮箱归属,通过 `--from` 指定发件人地址。ref: [lark-mail-send-as](references/lark-mail-send-as.md) | ||
| - 查看发送邮件后的投递状态:发送成功后查看邮件投递状态;也覆盖发送拦截。ref: [lark-mail-send-status](references/lark-mail-send-status.md) | ||
| - 使用邮件模板:区分个人模板和静态 HTML 模板,发信类 shortcut 用 `--template-id` 套用模板。ref: [lark-mail-template](references/lark-mail-template.md) | ||
| - 撤回已发送邮件:撤回邮件并查询异步撤回状态。ref: [lark-mail-recall](references/lark-mail-recall.md) | ||
| - 修改邮件标签/已读状态/文件夹:优先使用 `+message-modify`。ref: [`+message-modify`](references/lark-mail-message-modify.md) | ||
| - 软删除邮件:优先使用 `+message-trash`。ref: [`+message-trash`](references/lark-mail-message-trash.md) | ||
| - 收信规则:创建、验证、删除自动处理收到邮件的规则。ref: [lark-mail-rules](references/lark-mail-rules.md) | ||
| - 分享邮件到 IM:分享邮件或会话到群聊、个人会话。ref: [lark-mail-share-to-chat](references/lark-mail-share-to-chat.md) | ||
| - 发送日程邀请邮件:在邮件中嵌入 `text/calendar` 日程邀请。ref: [lark-mail-calendar-invite](references/lark-mail-calendar-invite.md) | ||
| - 编写复杂 HTML 正文:复杂 HTML、本地图片、安全不确定时读取规范或运行 `+lint-html`;普通正文无需预读。ref: [lark-mail-html](references/lark-mail-html.md) | ||
| - 读取邮件:按场景选择 triage、单封、批量或会话读取。ref: [`+triage`](references/lark-mail-triage.md)、[`+message`](references/lark-mail-message.md)、[`+messages`](references/lark-mail-messages.md)、[`+thread`](references/lark-mail-thread.md) | ||
| - 写信、草稿、回复、转发:先判断新邮件、回复或转发,再决定创建草稿、直接发送或定时发送。命令选择见下方;公共邮箱/别名、发送状态等见相关 ref。 | ||
|
|
||
| ### 参数不确定时先查 `-h` | ||
|
|
||
| 已有明确示例或已确认 flag 时可直接执行;参数、资源名或 raw API 结构不确定时,先运行 `-h` 查看可用参数,不要猜测参数名称: | ||
| 无论是 Shortcut(`+triage`、`+send` 等)还是原生 API,**首次调用前必须先运行 `-h` 查看可用参数**,不要猜测参数名称: |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Make the first-use order consistent.
The workflow says that user_mailboxes profile is the first mailbox command. Lines 115-117 require -h before any command.
Run the relevant -h command before profile, or state that the numbered workflow starts after the required help check.
🧰 Tools
🪛 SkillSpector (2.5.1)
[error] 32: [P1] Instruction Override: This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
Remediation: Remove or rewrite any text that instructs the agent to ignore prompts, override safety rules, or trust unverified content. Ensure skill content cannot be injected to alter agent behavior.
(Prompt Injection (P1))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/lark-mail/SKILL.md` around lines 115 - 117, Update the workflow around
the `user_mailboxes profile` step so the relevant `-h` command runs first, or
explicitly state that the numbered workflow begins after the mandatory initial
help check. Keep the existing `profile` operation and first-use ordering
consistent with the documented requirement.
| lark-cli mail +send --mailbox shared@example.com \ | ||
| --to bob@example.com --subject '通知' --body '<p>你好</p>' | ||
| ``` | ||
|
|
||
| **别名发信:** | ||
|
|
||
| ```bash | ||
| # --mailbox 指定所属邮箱,--from 指定别名地址 | ||
| lark-cli mail +send --mailbox me --from alias@example.com \ | ||
| --to bob@example.com --subject '测试' --body '<p>你好</p>' |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | rg '(^|/)SKILL\.md$|skill|lark-mail|capabilities|commands' || true
echo
echo "Relevant file sections:"
file="skills/lark-mail/SKILL.md"
if [ -f "$file" ]; then
wc -l "$file"
sed -n '70,105p' "$file"
echo "--- "
sed -n '200,218p' "$file"
echo "--- "
sed -n '225,237p' "$file"
echo "--- "
sed -n '510,530p' "$file"
fi
echo
echo "Search for --as user/--as auto and lark-cli mail send in repo:"
rg -n 'lark-cli mail .*mailbox|--as user|--as auto|--from alias|cancel_scheduled_send|\+draft-(create|send)|user_access_token|Feishu|open.feishu\.cn' . --glob '!node_modules' --glob '!dist' --glob '!build' || trueRepository: larksuite/cli
Length of output: 50372
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="skills/lark-mail/SKILL.md"
wc -l "$file"
echo "--- lines 1-110 ---"
sed -n '1,110p' "$file"
echo "--- lines 180-218 ---"
sed -n '180,218p' "$file"
echo "--- lines 225-237 ---"
sed -n '225,237p' "$file"
echo "--- lines 505-525 ---"
sed -n '505,525p' "$file"
echo "--- mail shortcut definitions ---"
for f in shortcuts/mail/mail_send.go shortcuts/mail/mail_draft_create.go shortcuts/mail/mail_draft_send.go; do
[ -f "$f" ] && { echo "### $f"; sed -n '1,90p' "$f"; }
doneRepository: larksuite/cli
Length of output: 26478
Keep mail write examples on the user identity.
Lines 88-91 require --as user for mail writes, but the public-mailbox and alias send examples, cancel_scheduled_send, and +draft-* examples still omit it. Add --as user to these examples, or document that the shortcuts enforce user identity.
🧰 Tools
🪛 SkillSpector (2.5.1)
[error] 32: [P1] Instruction Override: This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
Remediation: Remove or rewrite any text that instructs the agent to ignore prompts, override safety rules, or trust unverified content. Ensure skill content cannot be injected to alter agent behavior.
(Prompt Injection (P1))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/lark-mail/SKILL.md` around lines 207 - 216, Update the mail write
examples for public-mailbox and alias sends, cancel_scheduled_send, and all
+draft-* shortcuts to include the required --as user option, consistent with the
guidance on lines 88-91. If these shortcuts intentionally enforce user identity
instead, document that behavior explicitly.
| ```bash | ||
| # 发送带日程邀请的新邮件(先保存草稿,确认后发送) | ||
| lark-cli mail +send --as user \ | ||
| --to alice@example.com --cc bob@example.com \ | ||
| --subject '产品评审' \ | ||
| --body '<p>请参加本次产品评审会议。</p>' \ | ||
| --event-summary '产品评审' \ | ||
| --event-start '2026-05-10T14:00+08:00' \ | ||
| --event-end '2026-05-10T15:00+08:00' \ | ||
| --event-location '5F 大会议室' \ | ||
| --confirm-send |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Use a future calendar timestamp.
The example uses 2026-05-10T14:00+08:00 through 15:00. This date is before August 10, 2026.
Replace it with a clearly future date, or instruct the user to calculate a future Unix timestamp.
Proposed fix
- --event-start '2026-05-10T14:00+08:00' \
- --event-end '2026-05-10T15:00+08:00' \
+ --event-start '2030-05-10T14:00+08:00' \
+ --event-end '2030-05-10T15:00+08:00' \📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```bash | |
| # 发送带日程邀请的新邮件(先保存草稿,确认后发送) | |
| lark-cli mail +send --as user \ | |
| --to alice@example.com --cc bob@example.com \ | |
| --subject '产品评审' \ | |
| --body '<p>请参加本次产品评审会议。</p>' \ | |
| --event-summary '产品评审' \ | |
| --event-start '2026-05-10T14:00+08:00' \ | |
| --event-end '2026-05-10T15:00+08:00' \ | |
| --event-location '5F 大会议室' \ | |
| --confirm-send |
🧰 Tools
🪛 SkillSpector (2.5.1)
[error] 32: [P1] Instruction Override: This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
Remediation: Remove or rewrite any text that instructs the agent to ignore prompts, override safety rules, or trust unverified content. Ensure skill content cannot be injected to alter agent behavior.
(Prompt Injection (P1))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/lark-mail/SKILL.md` around lines 299 - 309, Update the example
command’s --event-start and --event-end values to use a clearly future calendar
date relative to August 10, 2026, while preserving the one-hour meeting duration
and timezone.
| - `list` — 列表/搜索指定用户邮箱的「信任发件人」白名单。支持按发件人地址或域名前缀搜索 (keyword)。返回列表按创建时间倒序,使用 page_token + page_size 进行分页。 | ||
|
|
||
| ### user_mailbox.blocked_senders | ||
|
|
||
| - `batch_create` — 批量将发件人加入指定用户邮箱的「屏蔽发件人」黑名单。支持按邮箱地址 (sender_type=1) 或域名 (sender_type=2) 添加。单次最多 100 项,单用户黑白名单合计最多 2000 项;与白名单互斥(添加黑名单会从白名单删除对侧记录)。 | ||
| - `batch_remove` — 批量从指定用户邮箱的「屏蔽发件人」黑名单中删除发件人。senders 中每项可以是邮箱地址或域名(与添加时一致)。批量删除按字面值哈希匹配,可兼容历史大写数据。单次最多 100 项。 | ||
| - `list` — 列表/搜索指定用户邮箱的「屏蔽发件人」黑名单。支持按发件人地址或域名前缀搜索 (keyword)。返回列表按创建时间倒序,使用 page_token + page_size 进行分页。 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
test -f cmd/service/mail_sender_generated_test.go
rg -n -C 5 \
'allow_senders|blocked_senders|message:(modify|readonly)|scope' \
cmd/service/mail_sender_generated_test.go \
skills/lark-mail/SKILL.mdRepository: larksuite/cli
Length of output: 23783
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
skill = Path("skills/lark-mail/SKILL.md").read_text()
contracts = Path("cmd/service/mail_sender_generated_test.go").read_text()
permission_tab = False
permission_lines = []
for line in skill.splitlines():
if re.match(r"\| 方法 \| 所需 scope \|", line):
permission_tab = True
continue
if permission_tab:
if re.match(r"\|--+", line):
continue
if re.match(r"\| [A-Za-z]", line):
permission_lines.append(line)
else:
permission_tab = False
print("permission rows involving allow_senders or blocked_senders:")
for row in permission_lines:
if "allow_senders" in row or "blocked_senders" in row:
print(row.strip())
print("\nrequired scopes from generated test:")
match = re.search(r"var mailSenderMethodContracts = \[\]mailSenderMethodContract\{(.*?)\};", contracts, re.S)
import ast
contract_block = match.group(1)
items = re.split(r"\},\s*\{", contract_block)
for item in items:
if "user_mailbox.allow_senders" in item or "user_mailbox.blocked_senders" in item:
resource = re.search(r"resource:\s*\"([^\"]+)\"", item).group(1)
method = re.search(r"method:\s*\"([^\"]+)\"", item).group(1)
scopes = re.search(r"requiredScopes:\s*\[\]string\{(.*)\?}", item, re.S).group(1)
scopes = re.sub(r"//.*", "", scopes)
scopes = [str.strip().strip('"') for str.strip().strip('"') in scopes.split(",") if str.strip().strip('"')]
print(f"{resource}.{method}: {scopes}")
PYRepository: larksuite/cli
Length of output: 376
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
skill = Path("skills/lark-mail/SKILL.md").read_text()
contracts = Path("cmd/service/mail_sender_generated_test.go").read_text()
permission_tab = False
permission_lines = []
for line in skill.splitlines():
if re.match(r"\| 方法 \| 所需 scope \|", line):
permission_tab = True
continue
if permission_tab:
if re.match(r"\|--+", line):
continue
if re.match(r"\| [A-Za-z]", line):
permission_lines.append(line)
else:
permission_tab = False
print("permission rows involving allow_senders or blocked_senders:")
for row in permission_lines:
if "allow_senders" in row or "blocked_senders" in row:
print(row.strip())
print("\nrequired scopes from generated test:")
match = re.search(r"var mailSenderMethodContracts = \[\]mailSenderMethodContract\{(.*?)\};", contracts, re.S)
contract_block = match.group(1)
items = re.split(r"\},\s*\{", contract_block)
for item in.items for item in items:
if "user_mailbox.allow_senders" in item or "user_mailbox.blocked_senders" in item:
resource = re.search(r"resource:\s*\"([^\"]+)\"", item).group(1)
method = re.search(r"method:\s*\"([^\"]+)\"", item).group(1)
scopes = re.search(r"requiredScopes:\s*\[\]string\{(.*)\?}", item, re.S).group(1)
scopes = re.sub(r"//.*", "", scopes)
scopes = [tok.strip().strip('"') for tok in scopes.split(",") if tok.strip()]
print(f"{resource}.{method}: {scopes}")
PYRepository: larksuite/cli
Length of output: 263
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
skill = Path("skills/lark-mail/SKILL.md").read_text()
contracts = Path("cmd/service/mail_sender_generated_test.go").read_text()
permission_tab = False
permission_lines = []
for line in skill.splitlines():
if re.match(r"\| 方法 \| 所需 scope \|", line):
permission_tab = True
continue
if permission_tab:
if re.match(r"\|--+", line):
continue
if re.match(r"\| [A-Za-z]", line):
permission_lines.append(line)
else:
permission_tab = False
print("permission_rows")
for row in permission_lines:
if "allow_senders" in row or "blocked_senders" in row:
print(row.strip())
print("\nrequired_scopes")
match = re.search(r"var mailSenderMethodContracts = \[\]mailSenderMethodContract\{(.*?)\};", contracts, re.S)
contract_block = match.group(1)
items = re.split(r"\},\s*\{", contract_block)
for item in items:
if "user_mailbox.allow_senders" in item or "user_mailbox.blocked_senders" in item:
resource = re.search(r"resource:\s*\"([^\"]+)\"", item).group(1)
method = re.search(r"method:\s*\"([^\"]+)\"", item).group(1)
scopes = re.search(r"requiredScopes:\s*\[\]string\{(.*)\?}", item, re.S).group(1)
scopes = re.sub(r"//.*", "", scopes)
tokens = [tok.strip().strip('"') for tok in scopes.split(",") if tok.strip()]
print(f"{resource}.{method}: {tokens}")
PYRepository: larksuite/cli
Length of output: 317
Document both required scopes for sender-list endpoints.
user_mailbox.allow_senders.list and user_mailbox.blocked_senders.list require mail:user_mailbox.message:readonly and mail:user_mailbox.message:modify per the generated contract. Update the permission table rows so users do not fail scope preflight with only modify.
Also applies to: 665-668
🧰 Tools
🪛 SkillSpector (2.5.1)
[error] 32: [P1] Instruction Override: This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
Remediation: Remove or rewrite any text that instructs the agent to ignore prompts, override safety rules, or trust unverified content. Ensure skill content cannot be injected to alter agent behavior.
(Prompt Injection (P1))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/lark-mail/SKILL.md` around lines 555 - 561, The permission table
entries for user_mailbox.allow_senders.list and
user_mailbox.blocked_senders.list currently omit a required scope. Update both
rows to document mail:user_mailbox.message:readonly and
mail:user_mailbox.message:modify, matching the generated contract and preserving
the existing endpoint descriptions.
|
|
Adds mail sender allowlist and blocklist management to the CLI.
Summary by CodeRabbit
Documentation
Tests