From 2767123c0eb6b24835463e61618198f2e2c20259 Mon Sep 17 00:00:00 2001 From: ipatool-gui Date: Thu, 22 Oct 2026 05:23:27 +0800 Subject: [PATCH 1/5] chore: drop .workbuddy from .gitignore The entry existed only for one maintainer's local assistant workspace, so it leaked a private directory name into every clone and forced other contributors to carry an ignore rule they never needed. Local-only paths belong in .git/info/exclude, which is per-clone and never committed. `.workbuddy/` is ignored there instead; nothing about the build changes. --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 28600ab..fb1e133 100644 --- a/.gitignore +++ b/.gitignore @@ -25,9 +25,6 @@ coverage/ *.tsbuildinfo .vitest-cache/ -# Local assistant workspace (never part of a build) -.workbuddy/ - # Local environment .env .env.* From 47b68f7c60977854ce8cc891a5d984f3230714a9 Mon Sep 17 00:00:00 2001 From: ipatool-gui Date: Thu, 22 Oct 2026 05:23:28 +0800 Subject: [PATCH 2/5] docs: add a bug report issue form and a CONTRIBUTING guide The first real bug report (#25) was a single screenshot. It turned out to be diagnosable - a macOS "Keychain Not Found" alert raised on behalf of the ipatool CLI - but only after someone read the image and guessed which layer produced it. A report that cannot name the app version, the OS, or the engine version costs a round-trip for every field. - .github/ISSUE_TEMPLATE/bug_report.yml asks for exactly those fields, plus reproducibility and the exported log, and asks reporters to say whether the problem is a vulnerability (those must not be public). - .github/ISSUE_TEMPLATE/config.yml turns off blank issues and points security reports, packaging questions and the install notes at the right place, so the form is not bypassed by an empty issue. - CONTRIBUTING.md documents the commands CI runs, which layer code belongs in, the two review rules that keep coming up (treat every IPC input as untrusted; say so when user-visible behaviour changes), and what makes a useful test. Documentation only: typecheck, lint and the full suite (482 tests) are unchanged and pass. --- .github/ISSUE_TEMPLATE/bug_report.yml | 109 ++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 11 +++ CONTRIBUTING.md | 96 +++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..c7a773d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,109 @@ +name: Bug report +description: Something in IPATool GUI does not work as expected +title: "[Bug] " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to report this. A screenshot helps, but a screenshot + alone usually cannot be acted on: the same dialog can come from the app, from + macOS, or from the `ipatool` CLI running underneath. The fields below are what + makes a report actionable. + + - type: checkboxes + id: preflight + attributes: + label: Before you file + options: + - label: I searched existing issues and this is not a duplicate. + required: true + - label: This is not a security vulnerability (those go through the Security tab, see below). + required: true + + - type: input + id: app-version + attributes: + label: App version + description: Settings → About in the app, or the installer filename. + placeholder: "0.1.1" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating system + options: + - Windows + - macOS (Apple Silicon) + - macOS (Intel) + - Linux (AppImage) + - Linux (deb) + - Other / building from source + validations: + required: true + + - type: input + id: os-version + attributes: + label: OS version + description: e.g. "Windows 11 23H2", "macOS 14.5", "Ubuntu 22.04". + placeholder: "macOS 14.5" + validations: + required: true + + - type: input + id: ipatool-version + attributes: + label: ipatool engine version + description: | + Shown in Settings → Engine, or from `ipatool --version`. The engine is downloaded + separately from the app, so this is often where a problem lives. + placeholder: "2.6.0" + validations: + required: false + + - type: textarea + id: what-happened + attributes: + label: What happened + description: What you did, what you expected, what you got instead. Exact error text is more useful than a description of it. + placeholder: | + 1. Opened the app, clicked "Sign in" + 2. Typed my Apple ID and password, clicked "Sign in" + 3. A macOS "Keychain Not Found" alert appeared: A keychain cannot be found to store "account". + 4. Expected: sign-in completes and the app shows my account. + validations: + required: true + + - type: dropdown + id: reproducibility + attributes: + label: Does it happen every time? + options: + - Every time + - Only the first time after launching + - Intermittently + - Only happened once + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Logs + description: | + Activity → **Export logs** in the app, then attach the file (drag it into this box). + Credentials and tokens are redacted automatically, but give it a quick skim before posting. + render: text + validations: + required: false + + - type: textarea + id: extra + attributes: + label: Anything else + description: Proxy/VPN, a recently migrated or reset keychain, antivirus, unusual locale — anything that might be relevant. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3a4d841 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Security vulnerability + url: https://github.com/a23bc/ipatool-gui/security + about: Please report vulnerabilities privately through the Security tab, not as a public issue. + - name: Build, test and release details + url: https://github.com/a23bc/ipatool-gui/blob/main/docs/architecture.md + about: Architecture, the security model, packaging and CI are documented here. + - name: Install / Gatekeeper / SmartScreen problems + url: https://github.com/a23bc/ipatool-gui#install + about: The README covers the "damaged" Gatekeeper warning and the SmartScreen prompt. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..67929b2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,96 @@ +# Contributing + +Thanks for helping. This is a small project, so the fastest way to get a change +merged is to keep it small and to show how you verified it. + +## Before you start + +- **Bugs vs. security.** Bugs go in the issue tracker (use the bug report form — it + asks for the app version, OS, engine version and logs). Anything that looks like a + vulnerability goes through the **Security** tab, not a public issue. +- **Open an issue first for anything larger than a typo.** A new feature, a new + dependency, or a change to the IPC surface is worth a sentence of agreement before + you write the code. +- **This repository ships no `ipatool` binary.** The app downloads it at runtime and + verifies the published SHA-256. Please do not add a bundled copy. + +## Development + +Requirements: Node 20.19+ and npm. + +```bash +npm install +npm run dev # Electron + Vite with HMR +``` + +Before opening a pull request, run the same checks CI runs: + +```bash +npm run typecheck +npm test # vitest, coverage gate enabled +npm run lint +npm run build +``` + +Packaging (rarely needed for a normal change): + +```bash +npm run dist:win # NSIS installer + portable exe +npm run dist:mac # .app (ad-hoc signed) +npm run dist:linux # AppImage + deb +``` + +## Where code goes + +The layering matters more than the file count — put logic in the lowest layer that +can hold it: + +| Path | What belongs there | +| --- | --- | +| `src/shared/` | Pure logic with no Electron or Node I/O: parsing, formatting, error classification, validation. **Fully unit-testable, and expected to be tested.** | +| `src/main/` | Electron main process: IPC handlers, queue, engine, settings, subprocess runner. | +| `src/preload/` | The frozen `window.api` bridge. Keep it a thin, explicit allow-list. | +| `src/renderer/` | React UI and zustand stores. Renderer state lives in stores, not components. | + +Two rules that come up in review: + +- **Everything crossing the IPC boundary is untrusted.** A renderer-supplied string + that becomes a path component or a URL segment must be validated in `src/main` + (see `src/shared/validate.ts`). Types do not survive the boundary. +- **User-visible behaviour changes need a sentence in the PR.** A different default, + a different error message, a new prompt — say so explicitly. + +## Tests + +- New logic in `src/shared/` needs tests. There is a per-area coverage gate, so an + untested module in the security-relevant paths will fail CI. +- `tests/` runs in the Node environment; `tests/dom/` covers renderer stores with a + stubbed `window.api`. +- A test that only proves "the code runs" is not worth much. Prefer one that fails + against the old behaviour — say in the PR what it catches. +- Signal/timing tests that cannot work on Windows should be scoped with + `describe.skipIf(process.platform === 'win32')` rather than deleted. + +## Style + +- Match the surrounding code. No reformatting of untouched lines, no "while I'm + here" refactors — they make a review impossible to follow. +- Comments explain **why**, not what. If a line looks odd, the reason it must be that + way belongs next to it. +- Commits: English, imperative mood, one logical change each (`fix(queue): ...`). +- No new runtime dependencies without discussing it first. +- Never commit credentials, tokens, or local-only files (editor config, scratch + scripts, exported logs). Keep those in `.git/info/exclude`, which is per-clone and + never pushed. + +## Pull requests + +- One concern per PR. If a change needs two independent explanations, it is two PRs. +- Describe: what was wrong, what you changed, how you verified it, and what you did + **not** verify. An honest "untested on macOS" is fine; a silent gap is not. +- CI must be green. `typecheck`, `test` and `build` all run on every PR. + +## Licence + +By contributing you agree that your work is licensed under the MIT licence, the same +as this project. From 157f123caa1a086780a949c9083c4845364f6ce5 Mon Sep 17 00:00:00 2001 From: ipatool-gui Date: Thu, 22 Oct 2026 05:35:29 +0800 Subject: [PATCH 3/5] docs: add SECURITY.md and a troubleshooting guide Two documents the project was missing, both aimed at the same problem: a report or a bug that costs a round-trip because the basic facts are not written down anywhere. SECURITY.md states what is in scope and what is not. The project ships unsigned binaries, downloads the engine at runtime and verifies it against a published SHA-256, and refuses to store credentials without an OS keystore - all deliberate, so "the binary is unsigned" or "the checksum failed" are not vulnerabilities. It also names the things that *are*: bypassing the verification, or reaching the credential store. It points at GitHub private vulnerability reporting, and says plainly that there is no bounty. docs/troubleshooting.md covers the four failures that actually get reported: the engine not being found or failing verification; macOS "Keychain Not Found" during sign-in (the alert comes from the ipatool CLI, not the app - it needs a default login keychain); the macOS "app is damaged" Gatekeeper message; and the network error codes, mapped to what to do about each. The error-code table was checked against IpatoolErrorCode and ENGINE_ERROR_CODES rather than written from memory, and both READMEs now link these documents. --- README.md | 4 +- README_CN.md | 4 +- SECURITY.md | 70 +++++++++++++++++++++++ docs/troubleshooting.md | 123 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 SECURITY.md create mode 100644 docs/troubleshooting.md diff --git a/README.md b/README.md index ebdfdf6..c02bca6 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,9 @@ More build, test, and release detail: [docs/architecture.md](docs/architecture.m | Doc | Contents | | --- | --- | | [docs/architecture.md](docs/architecture.md) | Multi-account model, pause/resume, progress parsing, security model, packaging & CI, code map | -| [Security](docs/architecture.md#安全披露) | Report vulnerabilities via Private vulnerability reporting — do not open a public issue | +| [docs/troubleshooting.md](docs/troubleshooting.md) | Engine not found, macOS keychain and Gatekeeper problems, proxy/network errors | +| [SECURITY.md](SECURITY.md) | What is in scope, and how to report a vulnerability privately — do not open a public issue | +| [CONTRIBUTING.md](CONTRIBUTING.md) | Development setup, the checks CI runs, where code belongs, what a useful test looks like | Worth knowing (details in the docs): diff --git a/README_CN.md b/README_CN.md index 763fc8a..563699c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -113,7 +113,9 @@ npm run dist:linux # AppImage + deb | 文档 | 内容 | | --- | --- | | [docs/architecture.md](docs/architecture.md) | 多账户模型、暂停续传原理、进度解析、安全模型、打包与 CI、代码地图 | -| [安全披露](docs/architecture.md#安全披露) | 漏洞请走 Private vulnerability reporting,勿开公开 issue | +| [docs/troubleshooting.md](docs/troubleshooting.md) | 引擎装不上、macOS 钥匙串与 Gatekeeper 问题、代理/网络报错对照表 | +| [SECURITY.md](SECURITY.md) | 安全边界与私密报告渠道,勿开公开 issue | +| [CONTRIBUTING.md](CONTRIBUTING.md) | 开发环境、CI 检查项、代码该放哪一层、什么算有用的测试 | 几个值得知道的设计点(细节在文档里): diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..f77a990 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,70 @@ +# Security Policy + +## Supported versions + +Only the **latest release** receives security fixes. There are no long-lived +maintenance branches for older versions; if you are on an older build, upgrade +before reporting. + +## Reporting a vulnerability + +**Please do not open a public issue.** + +Use GitHub's private vulnerability reporting: + + +That channel is private between you and the maintainer and lets a fix be prepared +before the details are public. + +A useful report contains: + +- the app version (Settings → About) and the OS + version; +- what an attacker gains, and what they need to start with; +- reproduction steps, ideally a minimal one; +- any relevant lines from Activity → Export logs (credentials and tokens are + redacted, but skim it first). + +If you are unsure whether something counts as a vulnerability, report it privately +anyway — a false positive costs far less than a public disclosure of a real one. + +## What this project assumes + +Worth knowing before you spend time on a report, because these are deliberate +design decisions rather than bugs: + +- **The app ships no `ipatool` binary.** It is downloaded on first launch and + verified against the SHA-256 published by the upstream release. The checksum + sidecar is always fetched from `github.com`, even when a download mirror is + configured — a mirror that supplied both the binary and its checksum could vouch + for a tampered artifact. A missing or unparseable checksum **fails closed**: the + binary is not installed. +- **Builds are not code signed** (Windows: unsigned; macOS: ad-hoc, not notarized). + Each release publishes `SHA256SUMS.txt`; that manifest is the provenance anchor. + "The binary is unsigned" is therefore a known limitation, not a vulnerability. + A way to make a *verified* download install something else **is** in scope. +- **Credentials are never written in plaintext.** They go to the OS keychain, or + through Electron's `safeStorage`; when neither is available the app refuses + rather than falling back to a plaintext file. +- **The renderer is treated as untrusted.** `sandbox` and `contextIsolation` are on, + the preload exposes a fixed API, every IPC input that becomes a path or a URL is + validated in the main process, and `fs:open-path` is restricted by an allow-list. + +## Out of scope + +- **Bugs in `ipatool` itself.** That is a separate project — report them at + . If this app passes a value to it in a way that + makes a bug exploitable, that part *is* in scope here. +- **Apple ID consequences.** Account flags, rate limits or terms-of-service actions + resulting from automated App Store access are not something a code change can fix. +- **Anything that requires existing code execution as your user**, administrator + rights, or physical access — including patching the app's own files. At that point + the attacker already has what they wanted. +- **Gatekeeper / SmartScreen warnings** about the unsigned build. These are expected + and documented in the README; see [docs/troubleshooting.md](docs/troubleshooting.md). + +## What to expect + +This is a small project maintained in spare time. There is **no bug bounty**. Reports +are acknowledged as soon as possible, and you will be told whether the issue is +accepted, needs more information, or is out of scope. Accepted issues are fixed in a +normal release; credit is given in the release notes unless you ask otherwise. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..ad38881 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,123 @@ +# Troubleshooting + +Start here for the four problems that come up most. If none of these match, open an +issue with the bug report form — it asks for the details this page keeps asking for. + +**Where the logs are:** Activity → **Export logs**. Credentials and tokens are +redacted automatically, but skim the file before sharing it. + +--- + +## The app cannot find or install the `ipatool` engine + +Settings → Engine shows what was detected and why it was rejected. + +| What you see | What it means | +| --- | --- | +| `ipatool was not found` | Not on `PATH`, not in the managed folder, and no path configured. Use **Install** in Settings → Engine, or point *ipatool path* at a real `ipatool` binary. | +| `not-executable` | A path is configured but it is not an `ipatool` binary. The basename must be exactly `ipatool` (`ipatool.exe` on Windows). A directory is also accepted — the app looks for `/ipatool` inside it. | +| `checksum-mismatch` | **This is the app protecting you.** The downloaded archive did not match the SHA-256 published by the upstream release, or the checksum sidecar was missing, unparseable, or described a different file. Nothing was installed. Retry; if it persists, download the release manually from and point *ipatool path* at it. | +| Download stalls behind a mirror | A GitHub mirror only accelerates the **asset** download. The checksum is still fetched from `github.com`, so a network that blocks `github.com` entirely will fail verification even with a mirror configured. | + +--- + +## macOS: "Keychain Not Found" while signing in + +You see a system alert titled **Keychain Not Found**: + +> A keychain cannot be found to store "account". + +The sign-in sheet behind it is the app's, but **the alert is macOS's own**, raised on +behalf of the `ipatool` command-line tool (the keychain icon in the alert carries a +small `exec` badge). `ipatool` stores the Apple ID credential in your login keychain; +if macOS cannot find a default keychain, the credential cannot be saved and sign-in +never completes. + +Check what the system thinks it has: + +```bash +security list-keychains +security default-keychain +``` + +- **If no default is set**, point it back at the login keychain: + + ```bash + security default-keychain -s ~/Library/Keychains/login.keychain-db + ``` + +- **If the "login" keychain is missing or damaged**, create one in Keychain Access + (File → New Keychain, name it `login`), unlock it, and set it as default with the + command above. + +- **Do not press "Reset To Defaults"** in that alert unless you mean it: on some macOS + versions it creates a new, empty keychain, which can make existing saved passwords + harder to reach. "Cancel" changes nothing. + +Migrating from a backup, or resetting the keychain recently, is a common cause. + +--- + +## macOS: "IPATool GUI is damaged and can't be opened" + +The download is fine — it is not notarized, and Gatekeeper reports the quarantine flag +as damage. After moving the app to `/Applications`, run once: + +```bash +xattr -dr com.apple.quarantine "/Applications/IPATool GUI.app" +``` + +Notes that catch people out: + +- `-r` is required: files inside the bundle are quarantined too. +- On macOS 15+, right-click → Open no longer bypasses Gatekeeper. The command above is + the simplest path; otherwise use System Settings → Privacy & Security → "Open Anyway". +- Extract with **Finder** or `tar -xzf`. Some third-party extractors drop symlinks or + the executable bit, which breaks the bundle for real. + +--- + +## Windows: SmartScreen blocks the installer + +The build is unsigned, so SmartScreen warns about an unknown publisher. Choose +**More info → Run anyway**. If your organisation blocks unsigned binaries by policy, +there is no per-user workaround — use the portable build or build from source. + +--- + +## Linux: AppImage will not start + +```bash +chmod +x IPATool-GUI-*.AppImage +./IPATool-GUI-*.AppImage +``` + +If it exits with a FUSE error, install `libfuse2` (Ubuntu 22.04+: +`sudo apt install libfuse2`). Alternatively use the `.deb`, which needs no FUSE. + +--- + +## Sign-in or download fails against Apple's endpoints + +Some networks cannot reach Apple's purchase/download hosts +(e.g. `p47-buy.itunes.apple.com`). The app classifies the failure for you: + +| Error | Meaning | What to do | +| --- | --- | --- | +| `dns` / `tls` / `network` | Could not reach Apple | Configure a system proxy or VPN, then retry. | +| `timeout` | Apple did not answer in time | Retry; first sign-in is often slow. | +| `rate-limited` | Too many requests | Wait; lowering Settings → Downloads → concurrency helps. | +| `app-not-found` | The App Store has no such app **for your storefront** | Check the country in Settings, and that the app exists in that storefront. | +| `version-not-found` | That version is not available for your account | Pick another version, or download the current one. | +| `resume-failed` | The partial file no longer matches the remote file | Retry — the app restarts the download from scratch. | +| `platform-mismatch` | The app does not support the selected platform | Switch the platform filter (iPhone / iPad / Mac). | +| `proxy` | The proxy refused the request or could not open a CONNECT tunnel | Check the proxy rules and credentials, or try without the proxy. | +| `disk` | No space left on the destination volume | Free space, or change the download directory in Settings. | + +--- + +## Reporting something not covered here + +Open an issue with the **bug report** form. It asks for the app version, OS, engine +version, reproducibility and logs — those five fields are what makes it possible to +act on a report instead of guessing. From 434c4b012543e7bfd36e4d5781fae3ac8f7b57fa Mon Sep 17 00:00:00 2001 From: ipatool-gui Date: Thu, 22 Oct 2026 05:35:30 +0800 Subject: [PATCH 4/5] docs: add a pull request template CONTRIBUTING.md asks for "what changed / how it was verified / what was not verified", but the box people actually type into had no prompts. This adds them, plus a checklist that mirrors what CI enforces. The "Not verified" section is deliberate: "no macOS machine, so codesign was not run" is useful information, while silence about it reads as a claim that everything was tested. --- .github/PULL_REQUEST_TEMPLATE.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..3eed6e5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,27 @@ +## What changed + + + +## Why + + + +## How it was verified + + + +## Not verified + + + +## Checklist + +- [ ] One concern only — unrelated changes are in another PR +- [ ] `npm run typecheck` passes +- [ ] `npm test` passes (coverage gate included) +- [ ] `npm run lint` passes +- [ ] New logic in `src/shared/` has tests +- [ ] No credential, token or local-only file is included +- [ ] User-visible behaviour changes are described above From bd937c06f727566c9f3bc272026ffca9600a4844 Mon Sep 17 00:00:00 2001 From: ipatool-gui Date: Thu, 22 Oct 2026 05:35:31 +0800 Subject: [PATCH 5/5] docs: add a Contributor Covenant code of conduct The issue form now asks people to be specific about failures, which only works if the project is a place where being wrong is safe. This states the expectation and gives a private reporting route. Adapted from Contributor Covenant 2.1; enforcement contact is the maintainer. --- CODE_OF_CONDUCT.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..7a9b312 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,92 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and maintainers pledge to make participation in this +project a harassment-free experience for everyone, regardless of age, body size, +visible or invisible disability, ethnicity, sex characteristics, gender identity and +expression, level of experience, education, socio-economic status, nationality, +personal appearance, race, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, +inclusive, and healthy community. + +## Our Standards + +Examples of behaviour that contributes to a positive environment: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologising to those affected by our mistakes, and + learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behaviour: + +- The use of sexualised language or imagery, and sexual attention or advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without + their explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional + setting + +## Enforcement Responsibilities + +Maintainers are responsible for clarifying and enforcing these standards and will take +appropriate and fair corrective action in response to any behaviour they deem +inappropriate, threatening, offensive, or harmful. + +Maintainers may remove, edit, or reject comments, commits, code, issues and other +contributions that are not aligned with this Code of Conduct, and will communicate the +reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all project spaces — issues, pull requests, +discussions, commit messages — and also when an individual is officially representing +the project in public spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported to +the maintainer privately, by contacting [@a23bc](https://github.com/a23bc) on GitHub. +Reports are reviewed promptly and handled confidentially; the reporter's identity is +kept private. Please do not use the Security tab for this — it is for vulnerabilities. + +All maintainers are obligated to respect the privacy and security of the reporter of any +incident. + +## Enforcement Guidelines + +Maintainers will follow these Community Impact Guidelines in determining the +consequences for any action they deem in violation of this Code of Conduct. + +**1. Correction.** *Community impact:* use of inappropriate language or other behaviour +deemed unprofessional or unwelcome. *Consequence:* a private, written warning, with +clarity around the nature of the violation and an explanation of why the behaviour was +inappropriate. + +**2. Warning.** *Community impact:* a violation through a single incident or series of +actions. *Consequence:* a warning with consequences for continued behaviour. No +interaction with the people involved for a specified period. Violating these terms may +lead to a temporary or permanent ban. + +**3. Temporary ban.** *Community impact:* a serious violation of community standards, +including sustained inappropriate behaviour. *Consequence:* a temporary ban from any +sort of interaction or public communication with the project for a specified period. + +**4. Permanent ban.** *Community impact:* demonstrating a pattern of violation of +community standards, including sustained inappropriate behaviour, harassment of an +individual, or aggression toward or disparagement of classes of individuals. +*Consequence:* a permanent ban from any sort of public interaction within the project. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, +available at +. + +[homepage]: https://www.contributor-covenant.org