README.md
6,401 bytes
| 1 | # profileShare |
|---|---|
| 2 | |
| 3 | profileShare creates time-limited, read-only snapshots of selected GitHub repositories. Anyone with a valid link can search the snapshot, switch frozen branches and tags, browse repositories and files, preview Markdown and raster images, open line-linked source, review file history, inspect commit diffs, read issues and pull request reviews, and inspect releases without a GitHub account. |
| 4 | |
| 5 | ## Requirements |
| 6 | |
| 7 | - Node.js 24 or later |
| 8 | - A GitHub account that can create a GitHub App |
| 9 | |
| 10 | Check your Node.js version: |
| 11 | |
| 12 | ```sh |
| 13 | node --version |
| 14 | ``` |
| 15 | |
| 16 | ## Local setup |
| 17 | |
| 18 | 1. Install dependencies: |
| 19 | |
| 20 | ```sh |
| 21 | npm install |
| 22 | ``` |
| 23 | |
| 24 | 2. Create a GitHub App at **GitHub Settings > Developer settings > GitHub Apps > New GitHub App**. Use these settings: |
| 25 | |
| 26 | | Setting | Local value | |
| 27 | | --- | --- | |
| 28 | | GitHub App name | Any unique name | |
| 29 | | Homepage URL | `http://localhost:3000` | |
| 30 | | Callback URL | `http://localhost:3000/auth/github/callback` | |
| 31 | | Setup URL | `http://localhost:3000/github/installed` | |
| 32 | | Webhook | Clear **Active** | |
| 33 | | Repository permissions: Contents | Read-only | |
| 34 | | Repository permissions: Issues | Read-only | |
| 35 | | Repository permissions: Metadata | Read-only | |
| 36 | | Repository permissions: Pull requests | Read-only | |
| 37 | | Where can this GitHub App be installed? | Only on this account | |
| 38 | |
| 39 | No webhook secret, private key, or user permission is needed. Keep **Request user authorization (OAuth) during installation** cleared because profileShare authorizes the owner before starting installation. |
| 40 | |
| 41 | 3. Open the new GitHub App's settings page and create a client secret. Copy the **Client ID**, generated client secret, and app slug. The slug is the final part of the app's public URL, such as `my-profile-share` in `https://github.com/apps/my-profile-share`. |
| 42 | |
| 43 | 4. Copy the example environment file: |
| 44 | |
| 45 | PowerShell: |
| 46 | |
| 47 | ```powershell |
| 48 | Copy-Item .env.example .env |
| 49 | ``` |
| 50 | |
| 51 | macOS or Linux: |
| 52 | |
| 53 | ```sh |
| 54 | cp .env.example .env |
| 55 | ``` |
| 56 | |
| 57 | 5. Fill in `.env`. Generate a stable session secret with: |
| 58 | |
| 59 | ```sh |
| 60 | node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))" |
| 61 | ``` |
| 62 | |
| 63 | Keep this secret unchanged while using the same database. It is used to encrypt stored GitHub access tokens. Changing it makes existing owner records unreadable. |
| 64 | |
| 65 | 6. Start the app: |
| 66 | |
| 67 | ```sh |
| 68 | npm start |
| 69 | ``` |
| 70 | |
| 71 | 7. Open `http://localhost:3000`, connect GitHub, and choose **Only select repositories** during GitHub App installation. Back in profileShare, select repositories, choose an expiry from 1 to 365 days, and create the link. |
| 72 | |
| 73 | For automatic restart while editing: |
| 74 | |
| 75 | ```sh |
| 76 | npm run dev |
| 77 | ``` |
| 78 | |
| 79 | ## Configuration |
| 80 | |
| 81 | | Variable | Required | Default | Purpose | |
| 82 | | --- | --- | --- | --- | |
| 83 | | `NODE_ENV` | No | None | Set to `production` for deployment safety checks | |
| 84 | | `GITHUB_CLIENT_ID` | Yes | None | GitHub App client ID | |
| 85 | | `GITHUB_CLIENT_SECRET` | Yes | None | GitHub App client secret | |
| 86 | | `GITHUB_APP_SLUG` | Yes | None | GitHub App URL slug | |
| 87 | | `SESSION_SECRET` | Yes | Development fallback | Token-encryption secret | |
| 88 | | `BASE_URL` | No | `http://localhost:3000` | Public origin used for OAuth callbacks and generated share links | |
| 89 | | `PORT` | No | `3000` | HTTP port | |
| 90 | | `DATABASE_PATH` | No | `data/profileshare.db` | SQLite database path | |
| 91 | |
| 92 | For a deployed instance, set `NODE_ENV=production`, set `BASE_URL` to its HTTPS origin, and update the GitHub App callback and setup URLs to the same origin. Generated links use `BASE_URL`, so it must be reachable by viewers. |
| 93 | |
| 94 | Snapshots are stored in the SQLite database. The owner workspace lists created links and lets the signed-in owner copy, open, or revoke active links. Revoking a link removes its stored repository content. When an expired link is opened, its stored snapshot content is removed and the expired message is shown. |
| 95 | |
| 96 | ## Verify |
| 97 | |
| 98 | Run the complete test suite: |
| 99 | |
| 100 | ```sh |
| 101 | npm test |
| 102 | ``` |
| 103 | |
| 104 | Run an individual spec check: |
| 105 | |
| 106 | ```sh |
| 107 | npm test -- auth |
| 108 | npm test -- snapshot |
| 109 | npm test -- e2e |
| 110 | ``` |
| 111 | |
| 112 | Manual acceptance check: |
| 113 | |
| 114 | 1. Create a link with a known set of repositories. |
| 115 | 2. Open it in a private browser window and confirm no viewer login is requested. |
| 116 | 3. Confirm only the selected repositories appear. |
| 117 | 4. Search for a file or code phrase across the snapshot. |
| 118 | 5. Switch between a repository's branches and tags, and confirm each ref shows its frozen files and commits. |
| 119 | 6. Open the Issues and Pull requests tabs, then inspect a conversation and a changed-file diff. |
| 120 | 7. Open Releases, inspect the release notes and asset metadata, and browse its tag. |
| 121 | 8. Confirm the repository overview shows topics, license, languages, stars, forks, branches, and tags. |
| 122 | 9. Browse a nested folder, preview a Markdown file and a raster image, switch Markdown to source, follow a line link, and open file history. |
| 123 | 10. Open a commit diff and confirm the full commit list appears for each selected repository. |
| 124 | 11. Filter the profile's repository tab by name and language. |
| 125 | 12. Change a source repository and confirm the existing link remains unchanged. |
| 126 | 13. Return to the owner workspace, revoke the link, and confirm the public URL no longer exposes repository content. |
| 127 | |
| 128 | ## Troubleshooting |
| 129 | |
| 130 | - **GitHub is not configured:** Confirm all three `GITHUB_*` values are present in `.env`, then restart the server. |
| 131 | - **Callback error or sign-in verification error:** Make sure `BASE_URL` and the GitHub App callback URL use the same origin, port, and protocol. Start sign-in again from the home page. |
| 132 | - **No repositories appear:** Open the GitHub App installation settings and grant it access to the intended repositories. The app lists only repositories selected for that installation. |
| 133 | - **Issues or pull requests do not appear:** Grant the GitHub App read-only Issues and Pull requests permissions, approve the updated installation permissions, then create a new snapshot. |
| 134 | - **Repository snapshot fails:** Confirm the GitHub App has read-only **Contents** and **Metadata** repository permissions and that the owner still has access. |
| 135 | - **Stored token errors after changing `SESSION_SECRET`:** Restore the previous secret, or move the local database aside and sign in again. Do not delete a database that contains snapshots you need. |
| 136 | - **The generated link points to localhost:** Set `BASE_URL` to the viewer-reachable HTTPS origin before creating the link. |
| 137 | - **Port conflict:** Set `PORT` and use the same port in `BASE_URL`, the callback URL, and the setup URL. |
| 138 | |