mirror of
https://github.com/Permissionless-Software-Foundation/x402-base-facilitator.git
synced 2026-09-21 16:52:01 -07:00
Added authentication helper for JSON RPC auth
This commit is contained in:
Generated
+93
-134
@@ -6584,7 +6584,8 @@
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
@@ -6787,7 +6788,8 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
@@ -13521,6 +13523,45 @@
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz",
|
||||
"integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.0",
|
||||
"ws": "~7.4.2"
|
||||
}
|
||||
},
|
||||
"engine.io-client": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.3.tgz",
|
||||
"integrity": "sha512-C3JYYyvna0FvSKOWGWpo0/EQ6MayO8uEKam1oedLZRpxLego9Fk6K3UH/Phieu1xPHauM7YqAygJ+6SraVc0Qg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.1",
|
||||
"has-cors": "1.1.0",
|
||||
"parseqs": "0.0.6",
|
||||
"parseuri": "0.0.6",
|
||||
"ws": "~7.4.2",
|
||||
"xmlhttprequest-ssl": "~1.5.4",
|
||||
"yeast": "0.1.2"
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4"
|
||||
}
|
||||
},
|
||||
"ipfs-utils": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ipfs-utils/-/ipfs-utils-6.0.4.tgz",
|
||||
@@ -13576,6 +13617,56 @@
|
||||
"version": "3.1.22",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz",
|
||||
"integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ=="
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz",
|
||||
"integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg=="
|
||||
},
|
||||
"socket.io-client-next": {
|
||||
"version": "npm:socket.io-client@3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.3.tgz",
|
||||
"integrity": "sha512-4sIGOGOmCg3AOgGi7EEr6ZkTZRkrXwub70bBB/F0JSkMOUFpA77WsL87o34DffQQ31PkbMUIadGOk+3tx1KGbw==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"backo2": "~1.0.2",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-client": "~4.1.0",
|
||||
"parseuri": "0.0.6",
|
||||
"socket.io-parser": "~4.0.4"
|
||||
}
|
||||
},
|
||||
"socket.io-next": {
|
||||
"version": "npm:socket.io@3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz",
|
||||
"integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.0",
|
||||
"@types/cors": "^2.8.8",
|
||||
"@types/node": ">=10.0.0",
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io": "~4.1.0",
|
||||
"socket.io-adapter": "~2.1.0",
|
||||
"socket.io-parser": "~4.0.3"
|
||||
}
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
|
||||
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
|
||||
"integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -19983,138 +20074,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io-client-next": {
|
||||
"version": "npm:socket.io-client@3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.3.tgz",
|
||||
"integrity": "sha512-4sIGOGOmCg3AOgGi7EEr6ZkTZRkrXwub70bBB/F0JSkMOUFpA77WsL87o34DffQQ31PkbMUIadGOk+3tx1KGbw==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"backo2": "~1.0.2",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-client": "~4.1.0",
|
||||
"parseuri": "0.0.6",
|
||||
"socket.io-parser": "~4.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"engine.io-client": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.2.tgz",
|
||||
"integrity": "sha512-1mwvwKYMa0AaCy+sPgvJ/SnKyO5MJZ1HEeXfA3Rm/KHkHGiYD5bQVq8QzvIrkI01FuVtOdZC5lWdRw1BGXB2NQ==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.1",
|
||||
"has-cors": "1.1.0",
|
||||
"parseqs": "0.0.6",
|
||||
"parseuri": "0.0.6",
|
||||
"ws": "~7.4.2",
|
||||
"xmlhttprequest-ssl": "~1.5.4",
|
||||
"yeast": "0.1.2"
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4"
|
||||
}
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
|
||||
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
|
||||
"integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io-next": {
|
||||
"version": "npm:socket.io@3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz",
|
||||
"integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.0",
|
||||
"@types/cors": "^2.8.8",
|
||||
"@types/node": ">=10.0.0",
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io": "~4.1.0",
|
||||
"socket.io-adapter": "~2.1.0",
|
||||
"socket.io-parser": "~4.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz",
|
||||
"integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "~0.4.1",
|
||||
"cors": "~2.8.5",
|
||||
"debug": "~4.3.1",
|
||||
"engine.io-parser": "~4.0.0",
|
||||
"ws": "~7.4.2"
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||
"requires": {
|
||||
"base64-arraybuffer": "0.1.4"
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz",
|
||||
"integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg=="
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
|
||||
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
|
||||
"requires": {
|
||||
"@types/component-emitter": "^1.2.10",
|
||||
"component-emitter": "~1.3.0",
|
||||
"debug": "~4.3.1"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
|
||||
"integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
|
||||
|
||||
@@ -145,6 +145,34 @@ class UserLib {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// Used to authenticate a user. If the login and password salt match a user in
|
||||
// the database, then it returns the user model. The Koa REST API uses the
|
||||
// Passport library for this functionality. This function is used to
|
||||
// authenticate users who login via the JSON RPC.
|
||||
async authUser (login, passwd) {
|
||||
try {
|
||||
// console.log('login: ', login)
|
||||
// console.log('passwd: ', passwd)
|
||||
|
||||
const user = await UserModel.findOne({ email: login })
|
||||
if (!user) {
|
||||
throw new Error('User not found')
|
||||
}
|
||||
|
||||
const isMatch = await user.validatePassword(passwd)
|
||||
|
||||
if (!isMatch) {
|
||||
throw new Error('Login credential do not match')
|
||||
}
|
||||
|
||||
return user
|
||||
} catch (err) {
|
||||
// console.error('Error in users.js/authUser()')
|
||||
console.log('')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserLib
|
||||
|
||||
@@ -59,6 +59,8 @@ class Auth {
|
||||
*/
|
||||
async authUser (ctx, next) {
|
||||
try {
|
||||
// Retrieve the user from the database after they've proven the correct
|
||||
// password.
|
||||
const user = await _this.passport.authUser(ctx, next)
|
||||
if (!user) {
|
||||
ctx.throw(401)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
This is the JSON RPC router for the users API
|
||||
*/
|
||||
|
||||
// Public npm libraries
|
||||
const jsonrpc = require('jsonrpc-lite')
|
||||
|
||||
// Local libraries
|
||||
const AuthLib = require('../../lib/auth')
|
||||
|
||||
class AuthRPC {
|
||||
constructor (localConfig) {
|
||||
// Encapsulate dependencies
|
||||
this.authLib = new AuthLib()
|
||||
this.jsonrpc = jsonrpc
|
||||
}
|
||||
|
||||
// Top-level router for this library. All other methods in this class are for
|
||||
// a specific endpoint. This method routes incoming calls to one of those
|
||||
// methods.
|
||||
async authRouter (rpcData) {
|
||||
try {
|
||||
console.log('authRouter rpcData: ', rpcData)
|
||||
|
||||
// if (rpcData.payload.method === 'getAll') return await this.getAll()
|
||||
|
||||
// Route the call based on the value of the method property.
|
||||
switch (rpcData.payload.method) {
|
||||
case 'getAll':
|
||||
return await this.getAll()
|
||||
case 'getUser':
|
||||
return await this.getUser(rpcData)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error in UsersRPC/rpcRouter()')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// Get all Users.
|
||||
async getAll () {
|
||||
try {
|
||||
console.log('Executing get all')
|
||||
const users = await this.userLib.getAllUsers()
|
||||
|
||||
const retJson = this.jsonrpc.success('getAll', users)
|
||||
const retStr = JSON.stringify(retJson, null, 2)
|
||||
|
||||
return retStr
|
||||
} catch (err) {
|
||||
console.error('Error in getAll()')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AuthRPC
|
||||
+5
-1
@@ -6,8 +6,9 @@
|
||||
const jsonrpc = require('jsonrpc-lite')
|
||||
|
||||
// Local support libraries
|
||||
const UserController = require('./users')
|
||||
const wlogger = require('../lib/wlogger')
|
||||
const UserController = require('./users')
|
||||
// const AuthController = require('./auth')
|
||||
|
||||
let _this
|
||||
|
||||
@@ -52,6 +53,9 @@ class JSONRPC {
|
||||
case 'users':
|
||||
retStr = await _this.userController.userRouter(parsedData)
|
||||
break
|
||||
case 'auth':
|
||||
retStr = await _this.authController.authRouter(parsedData)
|
||||
break
|
||||
}
|
||||
|
||||
return retStr
|
||||
|
||||
+12
-1
@@ -15,11 +15,22 @@ class UserRPC {
|
||||
this.jsonrpc = jsonrpc
|
||||
}
|
||||
|
||||
// Top-level router for this library. All other methods in this class are for
|
||||
// a specific endpoint. This method routes incoming calls to one of those
|
||||
// methods.
|
||||
async userRouter (rpcData) {
|
||||
try {
|
||||
console.log('userRouter rpcData: ', rpcData)
|
||||
|
||||
if (rpcData.payload.method === 'getAll') return await this.getAll()
|
||||
// if (rpcData.payload.method === 'getAll') return await this.getAll()
|
||||
|
||||
// Route the call based on the value of the method property.
|
||||
switch (rpcData.payload.method) {
|
||||
case 'getAll':
|
||||
return await this.getAll()
|
||||
case 'getUser':
|
||||
return await this.getUser(rpcData)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error in UsersRPC/rpcRouter()')
|
||||
throw err
|
||||
|
||||
@@ -26,10 +26,13 @@ describe('#users', () => {
|
||||
console.log(`Connecting to database: ${config.database}`)
|
||||
mongoose.Promise = global.Promise
|
||||
mongoose.set('useCreateIndex', true) // Stop deprecation warning.
|
||||
await mongoose.connect(config.database, {
|
||||
useUnifiedTopology: true,
|
||||
useNewUrlParser: true
|
||||
})
|
||||
await mongoose.connect(
|
||||
config.database,
|
||||
{
|
||||
useUnifiedTopology: true,
|
||||
useNewUrlParser: true
|
||||
}
|
||||
)
|
||||
|
||||
// Delete all previous users in the database.
|
||||
await testUtils.deleteAllUsers()
|
||||
@@ -312,7 +315,10 @@ describe('#users', () => {
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (err) {
|
||||
// console.log(err)
|
||||
assert.include(err.message, "Property 'type' can only be changed by Admin user")
|
||||
assert.include(
|
||||
err.message,
|
||||
"Property 'type' can only be changed by Admin user"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -336,6 +342,39 @@ describe('#users', () => {
|
||||
// TODO: verify that an admin can change the type of a user
|
||||
})
|
||||
|
||||
describe('#authUser', () => {
|
||||
it('should return a user db model after successful authentication', async () => {
|
||||
const user = await uut.authUser('test@test.com', 'password')
|
||||
// console.log('user: ', user)
|
||||
|
||||
assert.property(user, '_id')
|
||||
assert.property(user, 'email')
|
||||
assert.property(user, 'name')
|
||||
})
|
||||
|
||||
it('should throw an error if no user matches the login', async () => {
|
||||
try {
|
||||
await uut.authUser('noone@nowhere.com', 'password')
|
||||
// console.log('user: ', user)
|
||||
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (err) {
|
||||
assert.include(err.message, 'User not found')
|
||||
}
|
||||
})
|
||||
|
||||
it('should throw an error if password does not match', async () => {
|
||||
try {
|
||||
await uut.authUser('test@test.com', 'badpassword')
|
||||
// console.log('user: ', user)
|
||||
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (err) {
|
||||
assert.include(err.message, 'Login credential do not match')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('#deleteUser', () => {
|
||||
it('should throw error if no user provided', async () => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user