@tinyrack/issuary-server 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +51 -148
  3. package/readme.md +106 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tinyrack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@tinyrack/issuary-server",
3
- "version": "0.20.0",
4
- "private": false,
3
+ "version": "0.21.0",
5
4
  "type": "module",
6
5
  "description": "OpenID Connect Provider with OAuth2 support",
7
6
  "license": "MIT",
@@ -14,172 +13,123 @@
14
13
  "public",
15
14
  "dist"
16
15
  ],
17
- "publishConfig": {
18
- "exports": {
19
- ".": {
20
- "types": "./dist/entrypoints/index.d.ts",
21
- "default": "./dist/entrypoints/index.js"
22
- },
23
- "./config": {
24
- "types": "./dist/entrypoints/config/index.d.ts",
25
- "default": "./dist/entrypoints/config/index.js"
26
- },
27
- "./services": {
28
- "types": "./dist/entrypoints/services.d.ts",
29
- "default": "./dist/entrypoints/services.js"
30
- },
31
- "./database/postgres": {
32
- "types": "./dist/entrypoints/database/postgres/postgres.d.ts",
33
- "default": "./dist/entrypoints/database/postgres/postgres.js"
34
- },
35
- "./database/sqlite": {
36
- "types": "./dist/entrypoints/database/sqlite/sqlite.d.ts",
37
- "default": "./dist/entrypoints/database/sqlite/sqlite.js"
38
- },
39
- "./mail/nodemailer": {
40
- "types": "./dist/entrypoints/mail/nodemailer.d.ts",
41
- "default": "./dist/entrypoints/mail/nodemailer.js"
42
- },
43
- "./scheduler/croner": {
44
- "types": "./dist/entrypoints/scheduler/croner.d.ts",
45
- "default": "./dist/entrypoints/scheduler/croner.js"
46
- },
47
- "./scheduler/database": {
48
- "types": "./dist/entrypoints/scheduler/database.d.ts",
49
- "default": "./dist/entrypoints/scheduler/database.js"
50
- },
51
- "./identity-providers/github": {
52
- "types": "./dist/entrypoints/identity-providers/github.d.ts",
53
- "default": "./dist/entrypoints/identity-providers/github.js"
54
- },
55
- "./identity-providers/google": {
56
- "types": "./dist/entrypoints/identity-providers/google.d.ts",
57
- "default": "./dist/entrypoints/identity-providers/google.js"
58
- },
59
- "./identity-providers/apple": {
60
- "types": "./dist/entrypoints/identity-providers/apple.d.ts",
61
- "default": "./dist/entrypoints/identity-providers/apple.js"
62
- },
63
- "./identity-providers/generic-oauth": {
64
- "types": "./dist/entrypoints/identity-providers/generic-oauth.d.ts",
65
- "default": "./dist/entrypoints/identity-providers/generic-oauth.js"
66
- },
67
- "./frontend": {
68
- "types": "./dist/entrypoints/frontend/index.d.ts",
69
- "default": "./dist/entrypoints/frontend/index.js"
70
- },
71
- "./frontend/static": {
72
- "types": "./dist/entrypoints/frontend/static.d.ts",
73
- "default": "./dist/entrypoints/frontend/static.js"
74
- },
75
- "./frontend/proxy": {
76
- "types": "./dist/entrypoints/frontend/proxy.d.ts",
77
- "default": "./dist/entrypoints/frontend/proxy.js"
78
- }
79
- },
80
- "imports": {
81
- "#server/*.ts": "./dist/*.js",
82
- "#server/*.tsx": "./dist/*.js",
83
- "#server/*": {
84
- "types": "./dist/*",
85
- "default": "./dist/*"
86
- }
87
- }
88
- },
89
16
  "exports": {
90
17
  ".": {
91
- "@issuary/source": "./src/entrypoints/index.ts",
92
18
  "types": "./dist/entrypoints/index.d.ts",
93
19
  "default": "./dist/entrypoints/index.js"
94
20
  },
95
21
  "./config": {
96
- "@issuary/source": "./src/entrypoints/config/index.ts",
97
22
  "types": "./dist/entrypoints/config/index.d.ts",
98
23
  "default": "./dist/entrypoints/config/index.js"
99
24
  },
100
25
  "./services": {
101
- "@issuary/source": "./src/entrypoints/services.ts",
102
26
  "types": "./dist/entrypoints/services.d.ts",
103
27
  "default": "./dist/entrypoints/services.js"
104
28
  },
105
29
  "./database/postgres": {
106
- "@issuary/source": "./src/entrypoints/database/postgres/postgres.ts",
107
30
  "types": "./dist/entrypoints/database/postgres/postgres.d.ts",
108
31
  "default": "./dist/entrypoints/database/postgres/postgres.js"
109
32
  },
110
33
  "./database/sqlite": {
111
- "@issuary/source": "./src/entrypoints/database/sqlite/sqlite.ts",
112
34
  "types": "./dist/entrypoints/database/sqlite/sqlite.d.ts",
113
35
  "default": "./dist/entrypoints/database/sqlite/sqlite.js"
114
36
  },
115
37
  "./mail/nodemailer": {
116
- "@issuary/source": "./src/entrypoints/mail/nodemailer.ts",
117
38
  "types": "./dist/entrypoints/mail/nodemailer.d.ts",
118
39
  "default": "./dist/entrypoints/mail/nodemailer.js"
119
40
  },
120
41
  "./scheduler/croner": {
121
- "@issuary/source": "./src/entrypoints/scheduler/croner.ts",
122
42
  "types": "./dist/entrypoints/scheduler/croner.d.ts",
123
43
  "default": "./dist/entrypoints/scheduler/croner.js"
124
44
  },
125
45
  "./scheduler/database": {
126
- "@issuary/source": "./src/entrypoints/scheduler/database.ts",
127
46
  "types": "./dist/entrypoints/scheduler/database.d.ts",
128
47
  "default": "./dist/entrypoints/scheduler/database.js"
129
48
  },
130
49
  "./identity-providers/github": {
131
- "@issuary/source": "./src/entrypoints/identity-providers/github.ts",
132
50
  "types": "./dist/entrypoints/identity-providers/github.d.ts",
133
51
  "default": "./dist/entrypoints/identity-providers/github.js"
134
52
  },
135
53
  "./identity-providers/google": {
136
- "@issuary/source": "./src/entrypoints/identity-providers/google.ts",
137
54
  "types": "./dist/entrypoints/identity-providers/google.d.ts",
138
55
  "default": "./dist/entrypoints/identity-providers/google.js"
139
56
  },
140
57
  "./identity-providers/apple": {
141
- "@issuary/source": "./src/entrypoints/identity-providers/apple.ts",
142
58
  "types": "./dist/entrypoints/identity-providers/apple.d.ts",
143
59
  "default": "./dist/entrypoints/identity-providers/apple.js"
144
60
  },
145
61
  "./identity-providers/generic-oauth": {
146
- "@issuary/source": "./src/entrypoints/identity-providers/generic-oauth.ts",
147
62
  "types": "./dist/entrypoints/identity-providers/generic-oauth.d.ts",
148
63
  "default": "./dist/entrypoints/identity-providers/generic-oauth.js"
149
64
  },
150
65
  "./frontend": {
151
- "@issuary/source": "./src/entrypoints/frontend/index.ts",
152
66
  "types": "./dist/entrypoints/frontend/index.d.ts",
153
67
  "default": "./dist/entrypoints/frontend/index.js"
154
68
  },
155
69
  "./frontend/static": {
156
- "@issuary/source": "./src/entrypoints/frontend/static.ts",
157
70
  "types": "./dist/entrypoints/frontend/static.d.ts",
158
71
  "default": "./dist/entrypoints/frontend/static.js"
159
72
  },
160
73
  "./frontend/proxy": {
161
- "@issuary/source": "./src/entrypoints/frontend/proxy.ts",
162
74
  "types": "./dist/entrypoints/frontend/proxy.d.ts",
163
75
  "default": "./dist/entrypoints/frontend/proxy.js"
164
76
  }
165
77
  },
166
78
  "imports": {
167
- "#server/*.ts": {
168
- "@issuary/source": "./src/*.ts",
169
- "types": "./dist/*.d.ts",
170
- "default": "./dist/*.js"
171
- },
172
- "#server/*.tsx": {
173
- "@issuary/source": "./src/*.tsx",
174
- "types": "./dist/*.d.ts",
175
- "default": "./dist/*.js"
176
- },
79
+ "#server/*.ts": "./dist/*.js",
80
+ "#server/*.tsx": "./dist/*.js",
177
81
  "#server/*": {
178
- "@issuary/source": "./src/*",
179
82
  "types": "./dist/*",
180
83
  "default": "./dist/*"
181
84
  }
182
85
  },
86
+ "devDependencies": {
87
+ "@biomejs/biome": "^2.5.2",
88
+ "@react-email/preview-server": "^5.2.10",
89
+ "@types/node": "^24.13.3",
90
+ "@types/nodemailer": "^8.0.1",
91
+ "@types/pg": "^8.20.0",
92
+ "@types/qrcode": "^1.5.6",
93
+ "@types/react": "^19.2.17",
94
+ "@vitest/coverage-v8": "^4.1.10",
95
+ "tsx": "^4.23.0",
96
+ "typescript": "^5.9.3",
97
+ "vitest": "^4.1.10"
98
+ },
99
+ "dependencies": {
100
+ "@hono/standard-validator": "^0.2.3",
101
+ "@mikro-orm/cli": "^7.1.5",
102
+ "@mikro-orm/core": "^7.1.5",
103
+ "@mikro-orm/decorators": "^7.1.5",
104
+ "@mikro-orm/migrations": "^7.1.5",
105
+ "@mikro-orm/postgresql": "^7.1.5",
106
+ "@mikro-orm/seeder": "^7.1.5",
107
+ "@mikro-orm/sql": "^7.1.5",
108
+ "@react-email/components": "^1.0.12",
109
+ "@react-email/render": "^2.0.10",
110
+ "@react-email/tailwind": "^2.0.7",
111
+ "@scalar/hono-api-reference": "^0.11.8",
112
+ "@simplewebauthn/server": "^13.3.2",
113
+ "croner": "^10.0.1",
114
+ "hono": "^4.12.28",
115
+ "hono-openapi": "^1.3.1",
116
+ "jose": "^6.2.3",
117
+ "kysely": "^0.29.3",
118
+ "pino-pretty": "^13.1.3",
119
+ "react-email": "^6.6.6",
120
+ "nodemailer": "^9.0.3",
121
+ "otplib": "^13.4.1",
122
+ "pg": "^8.22.0",
123
+ "pino": "^10.3.1",
124
+ "qrcode": "^1.5.4",
125
+ "react": "^19.2.7",
126
+ "zod": "^4.4.3"
127
+ },
128
+ "mikro-orm": {
129
+ "configPaths": [
130
+ "./src/entrypoints/database/sqlite/cli.ts"
131
+ ]
132
+ },
183
133
  "scripts": {
184
134
  "test": "node --conditions=@issuary/source node_modules/vitest/vitest.mjs",
185
135
  "test:coverage": "node ../../packages/tools/src/scripts/rm.ts coverage && node --conditions=@issuary/source node_modules/vitest/vitest.mjs run --coverage --maxWorkers=1",
@@ -198,52 +148,5 @@
198
148
  "mikro-orm:debug": "mikro-orm debug",
199
149
  "mikro-orm:migration:create:postgres": "node ./scripts/create-migration-with-baseline.mjs postgres",
200
150
  "mikro-orm:migration:create:sqlite": "node ./scripts/create-migration-with-baseline.mjs sqlite"
201
- },
202
- "devDependencies": {
203
- "@biomejs/biome": "catalog:",
204
- "@react-email/preview-server": "catalog:",
205
- "@types/node": "catalog:",
206
- "@types/nodemailer": "catalog:",
207
- "@types/pg": "catalog:",
208
- "@types/qrcode": "catalog:",
209
- "@types/react": "catalog:",
210
- "@vitest/coverage-v8": "catalog:",
211
- "tsx": "catalog:",
212
- "typescript": "catalog:",
213
- "vitest": "catalog:"
214
- },
215
- "dependencies": {
216
- "@hono/standard-validator": "catalog:",
217
- "@mikro-orm/cli": "catalog:",
218
- "@mikro-orm/core": "catalog:",
219
- "@mikro-orm/decorators": "catalog:",
220
- "@mikro-orm/migrations": "catalog:",
221
- "@mikro-orm/postgresql": "catalog:",
222
- "@mikro-orm/seeder": "catalog:",
223
- "@mikro-orm/sql": "catalog:",
224
- "@react-email/components": "catalog:",
225
- "@react-email/render": "catalog:",
226
- "@react-email/tailwind": "catalog:",
227
- "@scalar/hono-api-reference": "catalog:",
228
- "@simplewebauthn/server": "catalog:",
229
- "croner": "catalog:",
230
- "hono": "catalog:",
231
- "hono-openapi": "catalog:",
232
- "jose": "catalog:",
233
- "kysely": "catalog:",
234
- "pino-pretty": "catalog:",
235
- "react-email": "catalog:",
236
- "nodemailer": "catalog:",
237
- "otplib": "catalog:",
238
- "pg": "catalog:",
239
- "pino": "catalog:",
240
- "qrcode": "catalog:",
241
- "react": "catalog:",
242
- "zod": "catalog:"
243
- },
244
- "mikro-orm": {
245
- "configPaths": [
246
- "./src/entrypoints/database/sqlite/cli.ts"
247
- ]
248
151
  }
249
- }
152
+ }
package/readme.md ADDED
@@ -0,0 +1,106 @@
1
+ <div align="center">
2
+
3
+ # Issuary
4
+
5
+ **A lightweight, self-hosted OpenID Connect provider for modern applications.**
6
+
7
+ [![CI](https://github.com/tinyrack-net/issuary/actions/workflows/ci.yml/badge.svg)](https://github.com/tinyrack-net/issuary/actions/workflows/ci.yml)
8
+ [![npm server](https://img.shields.io/npm/v/@tinyrack/issuary-server?label=server)](https://www.npmjs.com/package/@tinyrack/issuary-server)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D24-brightgreen)](https://nodejs.org/)
11
+
12
+ [Documentation](https://issuary.tinyrack.net/en/) · [Configuration](https://issuary.tinyrack.net/en/configuration/overview/) · [한국어](https://issuary.tinyrack.net/ko/)
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ Issuary is a self-hosted OpenID Connect (OIDC) provider that gives your apps a standards-based login system without bringing in a full identity platform.
19
+
20
+ It supports OAuth2/OIDC authorization code flows, PKCE, password login, passkeys, TOTP, social login, and a customizable multilingual frontend. Run it as a standalone server, ship it with Docker, or embed the server package in your own Node.js application.
21
+
22
+ ## Features
23
+
24
+ - **OIDC/OAuth2 provider** with authorization code flow, PKCE, discovery, token, userinfo, introspection, revocation, RP-initiated logout, client credentials, and device authorization endpoints
25
+ - **Multiple sign-in methods** including password, passkeys/WebAuthn, GitHub, Google, Apple, and generic OAuth/OIDC providers
26
+ - **Two-factor authentication** with TOTP and passkey-based second factors
27
+ - **Config-driven deployment** through a single YAML file
28
+ - **Customizable frontend** with themes, branding, background images, language selection, and terms flows
29
+ - **Database support** for SQLite and PostgreSQL
30
+ - **Standalone or embedded usage** through Docker or `@tinyrack/issuary-server`
31
+
32
+ ## Installation
33
+
34
+ ### Docker
35
+
36
+ ```bash
37
+ docker run --rm \
38
+ -p 8080:8080 \
39
+ -v ./config.yaml:/opt/config.yaml \
40
+ ghcr.io/tinyrack-net/issuary:latest
41
+ ```
42
+
43
+ ### Server package
44
+
45
+ Use the server package when you want to embed Issuary in your own Node.js runtime.
46
+
47
+ ```bash
48
+ npm install @tinyrack/issuary-server
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ Create a minimal `config.yaml`:
54
+
55
+ ```yaml
56
+ app:
57
+ host: http://localhost:8080
58
+ port: 8080
59
+
60
+ security:
61
+ session_secret: change-me-session-secret
62
+ hash_secret: change-me-hash-secret
63
+
64
+ database:
65
+ type: sqlite
66
+ path: ./data.db
67
+
68
+ basic_authentication_methods:
69
+ password:
70
+ enabled: true
71
+ passkey:
72
+ enabled: true
73
+ ```
74
+
75
+ Start Issuary:
76
+
77
+ ```bash
78
+ docker run --rm \
79
+ -p 8080:8080 \
80
+ -v ./config.yaml:/opt/config.yaml \
81
+ ghcr.io/tinyrack-net/issuary:latest
82
+ ```
83
+
84
+ Verify the OIDC discovery endpoint:
85
+
86
+ ```bash
87
+ curl http://localhost:8080/.well-known/openid-configuration
88
+ ```
89
+
90
+ OAuth/OIDC error responses from OAuth endpoints include the standard `error` and `error_description` fields for client compatibility. Issuary also preserves its internal `code` and `message` fields for existing API consumers.
91
+
92
+ Issuary only advertises implemented provider capabilities in discovery metadata. Register `client_credentials` only for confidential clients with a `client_secret`, and register `urn:ietf:params:oauth:grant-type:device_code` only for clients that should use the device authorization flow.
93
+
94
+ ## Examples
95
+
96
+ - `examples/clients/nextjs-ssr` — Next.js OIDC client with server-side token handling
97
+ - `examples/clients/react-spa` — React SPA using authorization code flow with PKCE
98
+ - `examples/servers/node-hono-sqlite` — Hono + SQLite deployment using `@tinyrack/issuary-server` and the bundled frontend
99
+
100
+ ## Documentation
101
+
102
+ For configuration guides, client integration examples, deployment notes, and the API reference, visit the **[Issuary documentation site](https://issuary.tinyrack.net/en/)**.
103
+
104
+ ## License
105
+
106
+ [MIT](LICENSE)