Documentation cleanup for public release (#38)
* docs: cleanup for public release (fix stale/wrong API docs, LICENSE, versions)
Documentation cleanup ahead of the public release announcement. Fixes a set
of confirmed issues from a prior audit:
- LICENSE: fill in MIT template placeholders (theta42, 2026).
- README.md: fix broken API docs link (api.md -> API.md), correct required
Node.js version (13.x -> 20.x), add the missing app_sso_invite group to
the LDAP groups table, scrub hardcoded dc=theta42,dc=com to the generic
dc=example,dc=com used elsewhere, add a "Recommended: Docker or
install.sh" section pointing to DEPLOYMENT.md/docs before the manual
OpenLDAP walkthrough, and drop an emoji from a warning callout.
- nodejs/api.md: deleted — it was a stale/legacy doc with wrong routes,
wrong request bodies, and endpoints that are dead/commented-out code.
The root API.md is the accurate, current reference; README now links
there directly.
- API.md: add the missing app_sso_invite permission group, fix the
documented invite response to match the real {token, link, mail_sent}
payload, document the previously-undocumented GET/PUT/DELETE
/api/user/invite endpoints, add the real allowed_groups field to the
OAuth client management examples, and document POST /api/oauth/authorize
(the endpoint that actually issues the code after consent).
- nodejs/routes/auth.js + API.md: fix "emaill address" typo in the
password-reset response message (source and docs kept in sync).
- DEPLOYMENT.md: fix the top-level summary to mention Redis, matching
docs/deployment.md and the entrypoint behavior it already documents.
Flagged, not changed: tos.md reads like a personal home-lab acceptable-use
policy (Emby/Gitea/Proxmox/Discord/Signal, first-person "the admin") rather
than generic OSS docs. Left in place pending a manual decision to
genericize, relocate, or remove it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* docs: genericize tos.md template, track runtime-editable terms in #39
Removes operator-specific references (Emby, Gitea, Proxmox, Discord,
Signal, first-person "the admin") so the shipped tos.md reads as a
neutral starting template rather than one operator's internal policy.
Actual runtime editability (admin/legal editing terms without a code
change) is tracked in issue #39, not implemented here.
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,7 @@ auth-token: <token>
|
|||||||
|-------|--------|
|
|-------|--------|
|
||||||
| `app_sso_admin` | Full user/group/notification management |
|
| `app_sso_admin` | Full user/group/notification management |
|
||||||
| `app_sso_oauth_admin` | Register and manage OAuth clients |
|
| `app_sso_oauth_admin` | Register and manage OAuth clients |
|
||||||
|
| `app_sso_invite` | Invitation management |
|
||||||
| Group owner | Manage membership of that specific group |
|
| Group owner | Manage membership of that specific group |
|
||||||
|
|
||||||
Self-service: users can always read and modify their own account without admin membership.
|
Self-service: users can always read and modify their own account without admin membership.
|
||||||
@@ -116,7 +117,7 @@ Returns available username suggestions based on name and optional date of birth.
|
|||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
```json
|
```json
|
||||||
{ "message": "If the emaill address is in our system, you will receive a message." }
|
{ "message": "If the email address is in our system, you will receive a message." }
|
||||||
```
|
```
|
||||||
|
|
||||||
The same response is returned whether or not the email exists. Reset tokens expire after 24 hours.
|
The same response is returned whether or not the email exists. Reset tokens expire after 24 hours.
|
||||||
@@ -506,11 +507,90 @@ When an admin changes another user's password, `password_must_change` is set on
|
|||||||
|
|
||||||
### Generate Invite Token
|
### Generate Invite Token
|
||||||
|
|
||||||
**`POST /api/user/invite`** — Any authenticated user
|
Create an invite token, optionally emailing it to the invitee and pre-assigning
|
||||||
|
LDAP groups the new account should be added to on signup.
|
||||||
|
|
||||||
|
**`POST /api/user/invite`** — `app_sso_admin` or `app_sso_invite` required
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```json
|
||||||
|
{ "mail": "invitee@example.com", "groups": ["group_name"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
`mail` and `groups` are both optional. If `mail` is provided, a verification
|
||||||
|
email is sent to that address.
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
```json
|
```json
|
||||||
{ "token": "invite_token_string" }
|
{
|
||||||
|
"token": "invite_token_string",
|
||||||
|
"link": "https://your-domain.com/login/invite/invite_token_string",
|
||||||
|
"mail_sent": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### List Invite Tokens
|
||||||
|
|
||||||
|
**`GET /api/user/invite`** — `app_sso_admin` or `app_sso_invite` required
|
||||||
|
|
||||||
|
Admins (`app_sso_admin`) see all invite tokens; non-admin `app_sso_invite`
|
||||||
|
members see only invites they created.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"token": "invite_token_string",
|
||||||
|
"created_by": "username",
|
||||||
|
"created_on": 1234567890000,
|
||||||
|
"is_valid": true,
|
||||||
|
"mail": "invitee@example.com",
|
||||||
|
"groups": "[\"group_name\"]"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Update Invite Token
|
||||||
|
|
||||||
|
Update the groups an invite will assign, or change/clear the invitee's email
|
||||||
|
(re-sends verification if a new email is set).
|
||||||
|
|
||||||
|
**`PUT /api/user/invite/:token`** — `app_sso_admin`, or the `app_sso_invite`
|
||||||
|
member who created the invite
|
||||||
|
|
||||||
|
**URL Parameters:** `token` — invite token
|
||||||
|
|
||||||
|
**Request:** Any subset of:
|
||||||
|
```json
|
||||||
|
{ "groups": ["group_name"], "mail": "newinvitee@example.com" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Set `mail` to `null`/empty to clear it. Fails with `400` if the token is no
|
||||||
|
longer valid.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{ "results": { "token": "invite_token_string", "is_valid": true, "...": "..." } }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Revoke Invite Token
|
||||||
|
|
||||||
|
**`DELETE /api/user/invite/:token`** — `app_sso_admin`, or the `app_sso_invite`
|
||||||
|
member who created the invite
|
||||||
|
|
||||||
|
**URL Parameters:** `token` — invite token
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{ "results": true }
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -831,7 +911,44 @@ Returns the OIDC discovery document with endpoint URLs, supported scopes, and si
|
|||||||
- `code_challenge` — PKCE challenge (SHA-256 of code_verifier, base64url-encoded)
|
- `code_challenge` — PKCE challenge (SHA-256 of code_verifier, base64url-encoded)
|
||||||
- `code_challenge_method` — Must be `S256`
|
- `code_challenge_method` — Must be `S256`
|
||||||
|
|
||||||
Renders the consent screen. On approval, redirects to `redirect_uri?code=<code>&state=<state>`.
|
Renders the consent screen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Authorize (Issue Code)
|
||||||
|
|
||||||
|
Issues the authorization code after the user approves the consent form shown
|
||||||
|
by the Authorization Endpoint above. This is called by the consent page itself
|
||||||
|
(an authenticated request, via `auth-token`), not by the OAuth client
|
||||||
|
directly.
|
||||||
|
|
||||||
|
**`POST /api/oauth/authorize`** — Auth required (`auth-token` header)
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"response_type": "code",
|
||||||
|
"client_id": "uuid",
|
||||||
|
"redirect_uri": "https://ha.example.com/auth/external/callback",
|
||||||
|
"scope": "openid profile email",
|
||||||
|
"state": "opaque-state-value",
|
||||||
|
"code_challenge": "pkce-challenge",
|
||||||
|
"code_challenge_method": "S256"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Only scopes the client is actually registered for are granted, even if more
|
||||||
|
are requested. If the client has `allowed_groups` set, the authenticated user
|
||||||
|
must be a member of at least one of those groups or the request is rejected
|
||||||
|
with `403`.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{ "redirect_url": "https://ha.example.com/auth/external/callback?code=<code>&state=<state>" }
|
||||||
|
```
|
||||||
|
|
||||||
|
The caller (the consent page) redirects the browser to `redirect_url`, which
|
||||||
|
completes the flow described in the Authorization Endpoint section above.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -916,6 +1033,7 @@ All endpoints require authentication and `app_sso_oauth_admin` membership.
|
|||||||
"description": "Home automation",
|
"description": "Home automation",
|
||||||
"redirect_uris": ["https://ha.example.com/auth/external/callback"],
|
"redirect_uris": ["https://ha.example.com/auth/external/callback"],
|
||||||
"scopes": ["openid", "profile", "email"],
|
"scopes": ["openid", "profile", "email"],
|
||||||
|
"allowed_groups": [],
|
||||||
"token_lifetime": { "access_token": 3600, "refresh_token": 2592000 },
|
"token_lifetime": { "access_token": 3600, "refresh_token": 2592000 },
|
||||||
"created_by": "wmantly",
|
"created_by": "wmantly",
|
||||||
"created_on": 1234567890000
|
"created_on": 1234567890000
|
||||||
@@ -937,11 +1055,13 @@ All endpoints require authentication and `app_sso_oauth_admin` membership.
|
|||||||
"description": "Home automation dashboard",
|
"description": "Home automation dashboard",
|
||||||
"redirect_uris": ["https://ha.example.com/auth/external/callback"],
|
"redirect_uris": ["https://ha.example.com/auth/external/callback"],
|
||||||
"scopes": ["openid", "profile", "email"],
|
"scopes": ["openid", "profile", "email"],
|
||||||
|
"allowed_groups": [],
|
||||||
"token_lifetime": { "access_token": 3600, "refresh_token": 2592000 }
|
"token_lifetime": { "access_token": 3600, "refresh_token": 2592000 }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`redirect_uris` may also be a newline-separated string. `scopes` may also be a space-separated string.
|
`redirect_uris` may also be a newline-separated string. `scopes` may also be a space-separated string.
|
||||||
|
`allowed_groups` restricts the client to members of the listed SSO groups (empty/omitted = any valid user).
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
```json
|
```json
|
||||||
@@ -968,7 +1088,7 @@ The `client_secret` is shown **only once**. Store it immediately.
|
|||||||
|
|
||||||
**`PUT /api/oauth/client/:client_id`**
|
**`PUT /api/oauth/client/:client_id`**
|
||||||
|
|
||||||
**Request:** Any subset of `name`, `description`, `redirect_uris`, `scopes`, `token_lifetime`, `is_valid`.
|
**Request:** Any subset of `name`, `description`, `redirect_uris`, `scopes`, `allowed_groups`, `token_lifetime`, `is_valid`.
|
||||||
|
|
||||||
**Response:** `{ "results": { <updated client> }, "message": "..." }`
|
**Response:** `{ "results": { <updated client> }, "message": "..." }`
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
Two supported deployment methods:
|
Two supported deployment methods:
|
||||||
|
|
||||||
1. **Docker** — a single all-in-one image bundling the app + OpenLDAP (`docker compose up`).
|
1. **Docker** — a single all-in-one image bundling the app + OpenLDAP + Redis (`docker compose up`).
|
||||||
2. **Bare metal** — `install.sh` on Debian/Ubuntu (installs Node.js, OpenLDAP, the app, and a systemd unit).
|
2. **Bare metal** — `install.sh` on Debian/Ubuntu (installs Node.js, OpenLDAP, Redis, the app, and a systemd unit).
|
||||||
|
|
||||||
## How configuration works
|
## How configuration works
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ as raw strings otherwise. Examples:
|
|||||||
|
|
||||||
## Method 1: Docker (all-in-one)
|
## Method 1: Docker (all-in-one)
|
||||||
|
|
||||||
The image (`Dockerfile.openldap`) bundles OpenLDAP and the app in one container.
|
The image (`Dockerfile.openldap`) bundles OpenLDAP, Redis, and the app in one container.
|
||||||
The app connects to the bundled slapd over `localhost:389` automatically; you only
|
The app connects to the bundled slapd over `localhost:389` automatically; you only
|
||||||
need to set a few secrets.
|
need to set a few secrets.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) <year> <copyright holders>
|
Copyright (c) 2026 theta42
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,31 @@
|
|||||||
# SSO manager
|
# SSO manager
|
||||||
|
|
||||||
## API docs
|
## API docs
|
||||||
[API docs](api.md)
|
[API docs](API.md)
|
||||||
|
|
||||||
## Server set up
|
## Server set up
|
||||||
|
|
||||||
|
### Recommended: Docker or install.sh
|
||||||
|
|
||||||
|
The supported, tested deployment paths are **Docker** (an all-in-one image
|
||||||
|
bundling the app + OpenLDAP + Redis) and the **`install.sh`** bare-metal
|
||||||
|
installer for Debian/Ubuntu. Most users should start there:
|
||||||
|
|
||||||
|
- [Deployment Guide](DEPLOYMENT.md) — Docker + bare metal, configuration
|
||||||
|
layers, backups, troubleshooting.
|
||||||
|
- [docs/index.md](docs/index.md) — documentation home (also published as a
|
||||||
|
GitHub Pages site), with links to configuration, LDAP, and OAuth/OIDC docs.
|
||||||
|
|
||||||
|
### Manual / advanced: raw OpenLDAP setup
|
||||||
|
|
||||||
|
The rest of this section walks through configuring OpenLDAP by hand. This is
|
||||||
|
the **manual/advanced path** — useful if you're pointing the app at an
|
||||||
|
existing LDAP server, or want to understand exactly what `install.sh` and the
|
||||||
|
Docker entrypoint automate for you. Most deployments should use Docker or
|
||||||
|
`install.sh` above instead.
|
||||||
|
|
||||||
The server requires:
|
The server requires:
|
||||||
* NodeJS 13.x
|
* NodeJS 20.x
|
||||||
* LDAP server
|
* LDAP server
|
||||||
|
|
||||||
> Setting up the whole stack (Docker) or want the secrets-file layout? See
|
> Setting up the whole stack (Docker) or want the secrets-file layout? See
|
||||||
@@ -63,11 +82,11 @@ EOF
|
|||||||
|
|
||||||
**2. Add the overlay to your user database:**
|
**2. Add the overlay to your user database:**
|
||||||
|
|
||||||
> ⚠️ The database index below (`{1}mdb`) is **not** the same on every install. Confirm yours first — the overlay must go on the database whose `olcSuffix` is your base DN, or account locking silently won't apply to your users:
|
> Warning: The database index below (`{1}mdb`) is **not** the same on every install. Confirm yours first — the overlay must go on the database whose `olcSuffix` is your base DN, or account locking silently won't apply to your users:
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config \
|
> ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config \
|
||||||
> '(&(objectClass=olcDatabaseConfig)(olcSuffix=dc=theta42,dc=com))' dn
|
> '(&(objectClass=olcDatabaseConfig)(olcSuffix=dc=example,dc=com))' dn
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -76,7 +95,7 @@ dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
|
|||||||
objectClass: olcOverlayConfig
|
objectClass: olcOverlayConfig
|
||||||
objectClass: olcPPolicyConfig
|
objectClass: olcPPolicyConfig
|
||||||
olcOverlay: ppolicy
|
olcOverlay: ppolicy
|
||||||
olcPPolicyDefault: cn=ppolicy,ou=policies,dc=theta42,dc=com
|
olcPPolicyDefault: cn=ppolicy,ou=policies,dc=example,dc=com
|
||||||
olcPPolicyUseLockout: TRUE
|
olcPPolicyUseLockout: TRUE
|
||||||
olcPPolicyHashCleartext: FALSE
|
olcPPolicyHashCleartext: FALSE
|
||||||
EOF
|
EOF
|
||||||
@@ -85,12 +104,12 @@ EOF
|
|||||||
**3. Create the policies container and default policy:**
|
**3. Create the policies container and default policy:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ldapadd -x -D "cn=admin,dc=theta42,dc=com" -W << 'EOF'
|
ldapadd -x -D "cn=admin,dc=example,dc=com" -W << 'EOF'
|
||||||
dn: ou=policies,dc=theta42,dc=com
|
dn: ou=policies,dc=example,dc=com
|
||||||
objectClass: organizationalUnit
|
objectClass: organizationalUnit
|
||||||
ou: policies
|
ou: policies
|
||||||
|
|
||||||
dn: cn=ppolicy,ou=policies,dc=theta42,dc=com
|
dn: cn=ppolicy,ou=policies,dc=example,dc=com
|
||||||
objectClass: top
|
objectClass: top
|
||||||
objectClass: organizationalRole
|
objectClass: organizationalRole
|
||||||
objectClass: pwdPolicy
|
objectClass: pwdPolicy
|
||||||
@@ -105,8 +124,8 @@ EOF
|
|||||||
Verify by locking a test account and confirming bind fails:
|
Verify by locking a test account and confirming bind fails:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ldapmodify -x -D "cn=admin,dc=theta42,dc=com" -W << 'EOF'
|
ldapmodify -x -D "cn=admin,dc=example,dc=com" -W << 'EOF'
|
||||||
dn: cn=testuser,ou=people,dc=theta42,dc=com
|
dn: cn=testuser,ou=people,dc=example,dc=com
|
||||||
changetype: modify
|
changetype: modify
|
||||||
replace: pwdAccountLockedTime
|
replace: pwdAccountLockedTime
|
||||||
pwdAccountLockedTime: 000001010000Z
|
pwdAccountLockedTime: 000001010000Z
|
||||||
@@ -153,6 +172,7 @@ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=theta42,cn=schema,cn=config" olcAttri
|
|||||||
|-------|---------|
|
|-------|---------|
|
||||||
| `app_sso_admin` | Full admin access: manage users, groups, OAuth clients |
|
| `app_sso_admin` | Full admin access: manage users, groups, OAuth clients |
|
||||||
| `app_sso_oauth_admin` | Manage OAuth clients only |
|
| `app_sso_oauth_admin` | Manage OAuth clients only |
|
||||||
|
| `app_sso_invite` | Invitation management |
|
||||||
|
|
||||||
## Logs (Docker)
|
## Logs (Docker)
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
## create invite token
|
|
||||||
|
|
||||||
**post** `/users/invite`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Content-Type: application/json" -H "auth-token: 0b06eb2e-4ca4-4881-9a0f-b8df55431cd1" -X POST https://proxy-host.com/users/invite
|
|
||||||
```
|
|
||||||
|
|
||||||
* 200 {"token":"5caf94d2-2c91-4010-8df7-968d10802b9d"}
|
|
||||||
|
|
||||||
|
|
||||||
## sing up
|
|
||||||
|
|
||||||
**post** `/auth/invite/<INVITE TOKEN>`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Content-Type: application/json" -X POST -d "{\"username\": \"test9\", \"password\": \"palm7\"}" https://proxy-host.com/auth/invite/b33d8819-ec64-4cf4-a6ec-77562d738fa4
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
* 200 {"user":"test9","token":"af662d8b-3d44-4110-8ad9-047dc752d97f"}
|
|
||||||
* 400 {"message":"Missing fields"}
|
|
||||||
* 401 {"message":"Token not valid"}
|
|
||||||
* 409 {"message":"username taken"}
|
|
||||||
|
|
||||||
|
|
||||||
## login
|
|
||||||
|
|
||||||
**post** `/auth/login`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Content-Type: application/json" -X POST -d '{"username": "test8", "password": "mypassword"}' https://proxy-host.com/auth/login
|
|
||||||
```
|
|
||||||
|
|
||||||
* 200 {"login":true,"token":"027d3964-7d81-4462-a6f9-2c1f9b40b4be"}
|
|
||||||
* 401 {"login":false}
|
|
||||||
|
|
||||||
|
|
||||||
## verify SSH key
|
|
||||||
|
|
||||||
**post** `/auth/verifykey`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Content-Type: application/json" -X POST -d "{\"key\":\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDM9vboz5YGgESsrR2e4JOeP2qtmQo2S8BjI+Y/VxPQ6WbNFzAkXxDniHcnPCrhkeX36SKINvMjWnt4XOK2S+X+1tCoXJzqtcKKyK0gx8ijBxcWVPxsMWjMYTGSVSKiKnt6CyQzrbVGJMh3iAQ8Yv1JwH+6SAtMgT8it7iLyntNFJCesh4I/znEG58A5VBbdUle1Ztz9afjj1CZns17jk7KPm9ig5DmuvdvnMEfhFjfKv1Rp6S5nxacMoTP4tJNSEUh55IicoWk94ii5GwUVLYgyMmzdlA32TqVLFpU2yAvdA9WSnBaI/ZyktlfI7YAmK2wFBsagr9Pq1TcUAY6rZ/GTMjDxExgdYn/FxlufcuqeNJsJXs2A+0xDS/9mv/yGQzNZrL8DrVhY2OKKLoH4Q7enDbhSgEFmJUJMqPxuPEgLEvKfzcURSvIwRj1iCEw6S4dhdaLJl2RRBb1ZWBQbE5ogIbvAl7GFJUAhj3pqYJnd30VENv1MkK+IoCS7EEP0caqL9RNAId0Plud7q2XElHqzkYUE+z+Q/LvGgclXK1ZmZejNaMnV53wfhAevfwVyNGK9i5gbwc1P2lplIa5laXCcVWezqELEkTpdjp4AeKmMuCr8rY8EnLKIcKWEOsX5UumztCow6e1E55v3VeHvRZLpw4DZP7EE0Q8B/jPFWqbCw== wmantly@gmail.com\"}" https://proxy-host.com/auth/verifykey
|
|
||||||
```
|
|
||||||
|
|
||||||
* 200 {"info":"4096 SHA256:dfdCYzt0atMBXVZTJzUxsu99IjXXFXpocSox5q+jOs8 wmantly@gmail.com (RSA)\n"}
|
|
||||||
* 400 {"message":"Key is not a public key file!"}
|
|
||||||
|
|
||||||
|
|
||||||
## add ssh key to current user
|
|
||||||
|
|
||||||
**post** `/users/key`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Content-Type: application/json" -H "auth-token: 8eff4f16-086d-40fd-acbd-7634b9a36117" -X POST -d "{\"key\": \"ssh-rsa AAAAB3NzaC1yc2EAAjWnt4XOK2S+X+1tCoXJzqtcKKyK0gx8ijBxcWVPxsMWjMYTGSVSKiKnt6CyQzrbVGJMh3iAQ8Yv1JwH+6SAtMgT8it7iLyntNFJCesh4I/znEG58A5VBbdUle1Ztz9afjj1CZns17jk7KPm9ig5DmuvdvnMEfhFjfKv1Rp6S5nxacMoTP4tJNSEUh55IicoWk94ii5GwUVLYgyMmzdlA32TqVLFpU2yAvdA9WSnBaI/ZyktlfI7YAmK2wFBsagr9Pq1TcUAY6rZ/GTMjDxExgdYn/FxlufcuqeNJsJXs2A+0xDS/9mv/yGQzNZrL8DrVhY2OKKLoH4Q7enDbhSgEFmJUJMqPxuPEgLEvKfzcURSvIwRj1iCEw6S4dhdaLJl2RRBb1ZWBQbE5ogIbvAl7GFJUAhj3pqYJnd30VENv1MkK+IoCS7EEP0caqL9RNAId0Plud7q2XElHqzkYUE+z+Q/LvGgclXK1ZmZejNaMnV53wfhAevfwVyNGK9i5gbwc1P2lplIa5laXCcVWezqELEkTpdjp4AeKmMuCr8rY8EnLKIcKWEOsX5UumztCow6e1E55v3VeHvRZLpw4DZP7EE0Q8B/jPFWqbCw== wmantly@gmail.co\"}" https://proxy-host.com/users/key
|
|
||||||
```
|
|
||||||
|
|
||||||
* 200 {"message":true}
|
|
||||||
* 400 {"message":"Bad SSH key"}
|
|
||||||
@@ -66,7 +66,7 @@ router.post('/resetpassword', rateLimit.passwordReset, async function(req, res,
|
|||||||
console.info('resetpassword for', req.body.mail, 'sent')
|
console.info('resetpassword for', req.body.mail, 'sent')
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
message: 'If the emaill address is in our system, you will receive a message.'
|
message: 'If the email address is in our system, you will receive a message.'
|
||||||
});
|
});
|
||||||
}catch(error){
|
}catch(error){
|
||||||
next(error);
|
next(error);
|
||||||
|
|||||||
@@ -2,19 +2,27 @@
|
|||||||
|
|
||||||
*Last updated: June 2026*
|
*Last updated: June 2026*
|
||||||
|
|
||||||
Welcome to Theta42. By creating an account and using any services on this system, you agree to the following terms. Please read them carefully — they're short and written in plain English.
|
> **This is a template.** SSO Manager ships this file as a starting point for
|
||||||
|
> operators to adapt to their own deployment, organization name, and
|
||||||
|
> jurisdiction. Replace the placeholder text below (or the whole document)
|
||||||
|
> with terms reviewed by your own admin/legal before relying on it. See
|
||||||
|
> [issue #39](https://github.com/theta42/sso-manager-node/issues/39) for the
|
||||||
|
> planned admin UI that will let operators edit this document without a code
|
||||||
|
> change.
|
||||||
|
|
||||||
|
Welcome. By creating an account and using any services on this system, you agree to the following terms. Please read them carefully — they're short and written in plain English.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Who This Applies To
|
## 1. Who This Applies To
|
||||||
|
|
||||||
These terms apply to anyone with an account on Theta42 systems, including but not limited to: SSH access, Emby, Gitea, self-managed containers or VMs, Proxmox, and any other services accessible with your credentials.
|
These terms apply to anyone with an account on this system, including but not limited to: SSH access, self-managed containers or VMs, and any other services accessible with your credentials.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Acceptable Use
|
## 2. Acceptable Use
|
||||||
|
|
||||||
- **Be respectful.** Treat other users and the admin with respect. Harassment, abuse, or intentionally disrupting other users' work is not tolerated.
|
- **Be respectful.** Treat other users and administrators with respect. Harassment, abuse, or intentionally disrupting other users' work is not tolerated.
|
||||||
- **Do no harm.** Do not attempt to access, modify, damage, or disrupt any system, service, or data you are not explicitly authorized to use — including systems outside this network.
|
- **Do no harm.** Do not attempt to access, modify, damage, or disrupt any system, service, or data you are not explicitly authorized to use — including systems outside this network.
|
||||||
- **No malicious activity.** Do not use your account to run port scans, exploits, denial-of-service attacks, spam campaigns, or any other activity intended to harm others.
|
- **No malicious activity.** Do not use your account to run port scans, exploits, denial-of-service attacks, spam campaigns, or any other activity intended to harm others.
|
||||||
- **No resource abuse.** Do not use shared infrastructure for cryptocurrency mining, bulk email, or other activities that consume excessive CPU, memory, disk, or bandwidth without prior approval.
|
- **No resource abuse.** Do not use shared infrastructure for cryptocurrency mining, bulk email, or other activities that consume excessive CPU, memory, disk, or bandwidth without prior approval.
|
||||||
@@ -23,36 +31,36 @@ These terms apply to anyone with an account on Theta42 systems, including but no
|
|||||||
|
|
||||||
## 3. Legal Compliance
|
## 3. Legal Compliance
|
||||||
|
|
||||||
- You agree to comply with all applicable **United States federal law** and the laws of **your current jurisdiction**.
|
- You agree to comply with all applicable laws in your jurisdiction and the jurisdiction where this service is operated.
|
||||||
- Do not store, transmit, access, or distribute any content that is illegal under US law or the laws where you are located.
|
- Do not store, transmit, access, or distribute any content that is illegal under applicable law.
|
||||||
- This includes but is not limited to: pirated software, copyrighted content you do not have rights to, and any material that is illegal in your jurisdiction.
|
- This includes but is not limited to: pirated software, copyrighted content you do not have rights to, and any material that is illegal in your jurisdiction.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Credential Security
|
## 4. Credential Security
|
||||||
|
|
||||||
- Do not share your password, SSH keys, or any other credentials with anyone — including the admin (who will never ask for your password).
|
- Do not share your password, SSH keys, or any other credentials with anyone — including administrators (who will never ask for your password).
|
||||||
- You are responsible for all activity that occurs under your account.
|
- You are responsible for all activity that occurs under your account.
|
||||||
- If you suspect your account has been compromised, notify the admin immediately and change your password.
|
- If you suspect your account has been compromised, notify an administrator immediately and change your password.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Self-Managed Resources
|
## 5. Self-Managed Resources
|
||||||
|
|
||||||
Users with access to containers, virtual machines, or Proxmox agree to additional responsibilities:
|
Users with access to containers or virtual machines agree to additional responsibilities:
|
||||||
|
|
||||||
- You are **fully responsible** for everything you run inside your allocated resources.
|
- You are **fully responsible** for everything you run inside your allocated resources.
|
||||||
- Keep your systems patched and reasonably secured. A compromised VM on the network is everyone's problem.
|
- Keep your systems patched and reasonably secured. A compromised VM on the network is everyone's problem.
|
||||||
- Do not use your allocation to attack, scan, or probe other systems — on this network or anywhere else.
|
- Do not use your allocation to attack, scan, or probe other systems — on this network or anywhere else.
|
||||||
- Resource abuse (running workloads that harm shared infrastructure or network performance) may result in immediate suspension of your allocation.
|
- Resource abuse (running workloads that harm shared infrastructure or network performance) may result in immediate suspension of your allocation.
|
||||||
- Do not expose services to the internet without coordinating with the admin.
|
- Do not expose services to the internet without coordinating with an administrator.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Privacy
|
## 6. Privacy
|
||||||
|
|
||||||
- Your personal data (name, email address, phone number) is stored solely to operate this service. It will not be sold, rented, or shared with third parties.
|
- Your personal data (name, email address, phone number) is stored solely to operate this service. It will not be sold, rented, or shared with third parties.
|
||||||
- **The admin reserves the right to inspect** activity logs, files, running processes, and system usage on shared infrastructure at any time — for security purposes, incident investigation, or to verify compliance with these terms.
|
- **Administrators reserve the right to inspect** activity logs, files, running processes, and system usage on shared infrastructure at any time — for security purposes, incident investigation, or to verify compliance with these terms.
|
||||||
- **You have no expectation of privacy** on systems, storage, or network traffic hosted on this infrastructure.
|
- **You have no expectation of privacy** on systems, storage, or network traffic hosted on this infrastructure.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -60,7 +68,7 @@ Users with access to containers, virtual machines, or Proxmox agree to additiona
|
|||||||
## 7. Account Termination
|
## 7. Account Termination
|
||||||
|
|
||||||
- Violation of any of these terms may result in **immediate account suspension or deletion without prior notice**.
|
- Violation of any of these terms may result in **immediate account suspension or deletion without prior notice**.
|
||||||
- The admin reserves sole discretion to terminate access for any reason.
|
- Administrators reserve sole discretion to terminate access for any reason.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -72,4 +80,4 @@ This agreement may be updated at any time. The current version is always availab
|
|||||||
|
|
||||||
## Questions?
|
## Questions?
|
||||||
|
|
||||||
Reach the admin through the SSO manager or through the associated communication channels (Discord, Signal, etc.).
|
Reach an administrator through the SSO manager or your organization's usual support channel.
|
||||||
|
|||||||
Reference in New Issue
Block a user