passlessjs 0.1.0 → 0.1.2
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.
- package/README.md +148 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,11 +1,149 @@
|
|
|
1
|
-
# passless
|
|
1
|
+
# passless - English 🇺🇸
|
|
2
|
+
|
|
3
|
+
A mini-library for Node.js that makes it easy to integrate OAuth login via Google and Yandex, as well as add Passkey (WebAuthn) authentication. Configuration is done via `.env`, with no unnecessary magic.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install passlessjs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Node.js 18+ (uses the built-in `fetch`).
|
|
12
|
+
|
|
13
|
+
## Environment Variables
|
|
14
|
+
|
|
15
|
+
Create a `.env` file (see `.env.example`):
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
PASSLESS_GOOGLE_CLIENT_ID=
|
|
19
|
+
PASSLESS_GOOGLE_CLIENT_SECRET=
|
|
20
|
+
PASSLESS_GOOGLE_REDIRECT_URI=
|
|
21
|
+
PASSLESS_YANDEX_CLIENT_ID=
|
|
22
|
+
PASSLESS_YANDEX_CLIENT_SECRET=
|
|
23
|
+
PASSLESS_YANDEX_REDIRECT_URI=
|
|
24
|
+
PASSLESS_RP_NAME=Passless Demo
|
|
25
|
+
PASSLESS_RP_ID=localhost
|
|
26
|
+
PASSLESS_ORIGIN=http://localhost:3000
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start (OAuth)
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const express = require('express');
|
|
33
|
+
const { Passless } = require('passlessjs');
|
|
34
|
+
require('dotenv').config();
|
|
35
|
+
|
|
36
|
+
const app = express();
|
|
37
|
+
const passless = new Passless();
|
|
38
|
+
|
|
39
|
+
app.get('/auth/google', (req, res) => {
|
|
40
|
+
const url = passless.getAuthUrl('google', req.query.state || '');
|
|
41
|
+
res.redirect(url);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
app.get('/auth/google/callback', async (req, res) => {
|
|
45
|
+
const { code } = req.query;
|
|
46
|
+
const result = await passless.exchangeCode('google', code);
|
|
47
|
+
// result.token and result.profile
|
|
48
|
+
res.json(result.profile);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
app.get('/auth/yandex', (req, res) => {
|
|
52
|
+
const url = passless.getAuthUrl('yandex', req.query.state || '');
|
|
53
|
+
res.redirect(url);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
app.get('/auth/yandex/callback', async (req, res) => {
|
|
57
|
+
const { code } = req.query;
|
|
58
|
+
const result = await passless.exchangeCode('yandex', code);
|
|
59
|
+
res.json(result.profile);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
app.listen(3000, () => console.log('http://localhost:3000'));
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Passkey (WebAuthn) Example
|
|
66
|
+
|
|
67
|
+
In a real project, replace `Map` with your database. Store `credentialStore` and `challengeStore` between restarts.
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const passless = new Passless({
|
|
71
|
+
passkey: {
|
|
72
|
+
rpId: 'localhost',
|
|
73
|
+
origin: 'http://localhost:3000',
|
|
74
|
+
rpName: 'Passless Demo',
|
|
75
|
+
},
|
|
76
|
+
credentialStore: new Map(),
|
|
77
|
+
challengeStore: new Map(),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Registration
|
|
81
|
+
app.get('/passkey/register/options', async (req, res) => {
|
|
82
|
+
const opts = await passless.createPasskeyRegistrationOptions({
|
|
83
|
+
userId: '123',
|
|
84
|
+
username: 'demo',
|
|
85
|
+
displayName: 'Demo User',
|
|
86
|
+
});
|
|
87
|
+
res.json(opts);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
app.post('/passkey/register/verify', express.json(), async (req, res) => {
|
|
91
|
+
const verification = await passless.verifyPasskeyRegistrationResponse({
|
|
92
|
+
response: req.body,
|
|
93
|
+
expectedChallenge: req.body.expectedChallenge,
|
|
94
|
+
});
|
|
95
|
+
res.json({ verified: verification.verified });
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Authentication
|
|
99
|
+
app.get('/passkey/authn/options', async (req, res) => {
|
|
100
|
+
const opts = await passless.createPasskeyAuthenticationOptions({ userId: '123' });
|
|
101
|
+
res.json(opts);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
app.post('/passkey/authn/verify', express.json(), async (req, res) => {
|
|
105
|
+
const verification = await passless.verifyPasskeyAuthenticationResponse({
|
|
106
|
+
response: req.body,
|
|
107
|
+
expectedChallenge: req.body.expectedChallenge,
|
|
108
|
+
});
|
|
109
|
+
res.json({ verified: verification.verified });
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API Overview
|
|
114
|
+
|
|
115
|
+
* `new Passless(config?)` — accepts `google`, `yandex`, `passkey`, as well as custom `credentialStore`/`challengeStore` (default is `Map`).
|
|
116
|
+
* `getAuthUrl(provider, state?)` — returns the authorization URL (`provider`: `google` | `yandex`).
|
|
117
|
+
* `exchangeCode(provider, code, overrideRedirectUri?)` — exchange `code` for a token and profile.
|
|
118
|
+
* `createPasskeyRegistrationOptions({ userId, username, displayName })` — get options for WebAuthn registration.
|
|
119
|
+
* `verifyPasskeyRegistrationResponse({ response, expectedChallenge })` — verify the registration response.
|
|
120
|
+
* `createPasskeyAuthenticationOptions({ userId })` — options for passkey login.
|
|
121
|
+
* `verifyPasskeyAuthenticationResponse({ response, expectedChallenge })` — verify the authentication response.
|
|
122
|
+
|
|
123
|
+
## Limitations
|
|
124
|
+
|
|
125
|
+
* The examples use in-memory stores; replace them with a persistent database.
|
|
126
|
+
* For production, add checks for the expiration of `state`/`challenge` and use HTTPS.
|
|
127
|
+
* Ensure that `PASSLESS_ORIGIN` and `PASSLESS_RP_ID` match the real domain.
|
|
128
|
+
|
|
129
|
+
### Extensibility
|
|
130
|
+
|
|
131
|
+
Passless uses a provider-based architecture. Any OAuth2 provider (Apple, GitHub, Discord, etc.) can be added without changing the core.
|
|
132
|
+
|
|
133
|
+
### Pull Requests
|
|
134
|
+
|
|
135
|
+
I welcome any contributions!
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# passless - Ru 🇷🇺
|
|
2
140
|
|
|
3
141
|
Мини-библиотека для Node.js, которая помогает быстро подружиться с OAuth входом через Google и Yandex, а также добавить вход по Passkey (WebAuthn). Конфигурация через `.env`, без лишней магии.
|
|
4
142
|
|
|
5
143
|
## Установка
|
|
6
144
|
|
|
7
145
|
```bash
|
|
8
|
-
npm install
|
|
146
|
+
npm install passlessjs
|
|
9
147
|
```
|
|
10
148
|
|
|
11
149
|
Требуется Node.js 18+ (используется встроенный `fetch`).
|
|
@@ -30,7 +168,7 @@ PASSLESS_ORIGIN=http://localhost:3000
|
|
|
30
168
|
|
|
31
169
|
```js
|
|
32
170
|
const express = require('express');
|
|
33
|
-
const { Passless } = require('
|
|
171
|
+
const { Passless } = require('passlessjs');
|
|
34
172
|
require('dotenv').config();
|
|
35
173
|
|
|
36
174
|
const app = express();
|
|
@@ -126,3 +264,10 @@ app.post('/passkey/authn/verify', express.json(), async (req, res) => {
|
|
|
126
264
|
- В примерах используются in-memory хранилища; замените на постоянную БД.
|
|
127
265
|
- Для продакшена добавьте проверку срока жизни `state`/`challenge` и HTTPS.
|
|
128
266
|
- Следите, чтобы `PASSLESS_ORIGIN` и `PASSLESS_RP_ID` совпадали с реальным доменом.
|
|
267
|
+
|
|
268
|
+
### Расширяемость
|
|
269
|
+
Passless использует провайдерную архитектуру. Любой OAuth2-провайдер
|
|
270
|
+
(Apple, GitHub, Discord и др.) может быть добавлен без изменения ядра.
|
|
271
|
+
|
|
272
|
+
### Pull requests
|
|
273
|
+
буду рад видеть любые запросы
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "passlessjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Tiny helper for Google, Yandex OAuth and WebAuthn passkeys with .env support",
|
|
5
5
|
"main": "passless.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@simplewebauthn/server": "^9.0.1",
|
|
23
|
-
"dotenv": "^16.4.5"
|
|
23
|
+
"dotenv": "^16.4.5",
|
|
24
|
+
"passlessjs": "^0.1.0"
|
|
24
25
|
}
|
|
25
26
|
}
|