I am trying to register the multiple user at one time however I am getting error while doing it as
"error: [FabricCAClientService.js]: Failed to enroll 0006, error:%o message=Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]], stack=Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]
at IncomingMessage.response.on (/vagrant/Dfarm-app/node/node_modules/fabric-ca-client/lib/FabricCAClient.js:470:22)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
Failed to register user: Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]"
I am trying to implement with one user its running fine we I am trying to implement with multiple user its giving error.
Can anyone suggest me how can multiple user can register in Blockchain.
Please see below registerUser.js file
'use strict';
const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network');
const fs = require('fs');
const path = require('path');
// capture network variables from config.json
// var configPath = path.join(process.cwd(), 'config.json');
// const configJSON = fs.readFileSync(configPath, 'utf8');
var configJSON = fs.readFileSync('config.json');
var config = JSON.parse(configJSON);
var connection_file = config.connection_file;
var appAdmin = config.appAdmin;
var orgMSPID = config.orgMSPID;
var userName = config.userName;
var gatewayDiscovery = config.gatewayDiscovery;
const ccpPath = path.join(process.cwd(), connection_file);
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
async function main() {
try {
var userDetails = config.userDetails;
// console.log('test', userDetails)
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
for(var i=0; i< userDetails.length;i++){
// console.log('test',walletPath)
let userExists = await wallet.exists(userDetails[i].userName);
if (userExists) {
// console.log('test',userDetails[0].userName)
console.log(`An identity for the user ${userDetails[i].userName} already exists in the wallet`);
return;
}
}
// console.log('test',walletPath)
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists(appAdmin);
if (!adminExists) {
console.log(`An identity for the admin user ${appAdmin} does not exist in the wallet`);
console.log('Run the enrollAdmin.js application before retrying');
return;
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: appAdmin, discovery: gatewayDiscovery });
// Get the CA client object from the gateway for interacting with the CA.
const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();
// Register the user, enroll the user, and import the new identity into the wallet.
for(var i=0; i< userDetails.length;i++){
var secret = await ca.register({ enrollmentID:userDetails[i].enrollmentID,userName:userDetails[i].userName, role:userDetails[i].role }, adminIdentity);
var enrollment = await ca.enroll({ enrollmentID:userDetails[i].enrollmentID, enrollmentSecret: userDetails[i].enrollmentSecret });
var userIdentity = X509WalletMixin.createIdentity(orgMSPID, enrollment.certificate, enrollment.key.toBytes());
wallet.import(userDetails[i].userName, userIdentity);
console.log('Successfully registered and enrolled admin user ' + userDetails[i].userName + ' and imported it into the wallet');
}
} catch (error) {
console.error(`Failed to register user: ${error}`);
process.exit(1);
}
}
main();
The config.json file
{
"connection_file": "connection.json",
"appAdmin": "admin",
"appAdminSecret": "adminpw",
"orgMSPID": "DfarmadminMSP",
"caName": "ca.dfarmadmin.com",
"userDetails": [{"username":"user1","enrollmentID":"0006","role":"client","enrollmentSecret": "1234"},
{"username":"user2", "enrollmentID":"0002","role":"client","enrollmentSecret": "abcs" },
{"username":"user3", "enrollmentID":"0003","role":"client","enrollmentSecret": "9807" },
{"username":"user4","enrollmentID":"0004","role":"client","enrollmentSecret": "abcd" }
],
"gatewayDiscovery": { "enabled": false }
}
The connection.json file
{
"name": "basic-network",
"version": "1.0.0",
"client": {
"tlsEnable": false,
"adminUser": "admin",
"adminPassword": "adminpw",
"enableAuthentication": false,
"organization": "dfarmadmin",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
},
"orderer": "300"
}
}
},
"channels": {
"dfarmchannel": {
"orderers": [
"orderer.dfarmadmin.com"
],
"peers": {
"peer0.dfarmadmin.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"ledgerQuery": true,
"eventSource": true
},
"connection": {
"timeout": {
"peer": {
"endorser": "6000",
"eventHub": "6000",
"eventReg": "6000"
}
}
},
"peer0.dfarmretail.com": {
"endorsingPeer": false,
"chaincodeQuery": true,
"ledgerQuery": true,
"eventSource": false
}
}
}
},
"organizations": {
"dfarmadmin": {
"mspid": "DfarmadminMSP",
"peers": [
"peer0.dfarmadmin.com"
],
"certificateAuthorities": [
"ca.dfarmadmin.com"
]
},
"dfarmretail": {
"mspid": "DfarmretailMSP",
"peers": [
"peer0.dfarmretail.com"
],
"certificateAuthorities": [
"ca.dfarmadmin.com"
]
}
},
"orderers": {
"orderer.dfarmadmin.com": {
"url": "grpc://localhost:7050",
"eventUrl": "grpc://localhost:7053"
}
},
"peers": {
"peer0.dfarmadmin.com": {
"url": "grpc://localhost:7051"
},
"peer0.dfarmretail.com": {
"url": "grpc://localhost:8051"
}
},
"certificateAuthorities": {
"ca.dfarmadmin.com": {
"url": "http://localhost:7054",
"caName": "ca.dfarmadmin.com"
}
}
}
AdminIdentiy console
adminIdentity User {
_name: 'admin',
_roles: null,
_affiliation: '',
_enrollmentSecret: '',
_identity:
Identity {
_certificate: '-----BEGIN CERTIFICATE-----\nMIIB/jCCAaSgAwIBAgIUdrt0WjnSmGsX1WuBWvXVTizqFKUwCgYIKoZIzj0EAwIw\nbzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xFzAVBgNVBAoTDmRmYXJtYWRtaW4uY29tMRowGAYDVQQDExFj\nYS5kZmFybWFkbWluLmNvbTAeFw0xOTA4MTQxMTEyMDBaFw0yMDA4MTMxMTE3MDBa\nMCExDzANBgNVBAsTBmNsaWVudDEOMAwGA1UEAxMFYWRtaW4wWTATBgcqhkjOPQIB\nBggqhkjOPQMBBwNCAARXptenPPGpVnJsEFv0wmJeybDYNoClJCyAv3GcRPb04WLR\nAynEoSXf+jwYIjypV98oeR127haGcDo7jHUn0DnBo2wwajAOBgNVHQ8BAf8EBAMC\nB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUW1YmLO6OaZB7FwXv6Gu7yc9jhNMw\nKwYDVR0jBCQwIoAgeD1bXE22u42++Y2v96xX+EKLzk8JkEcheGl5g8XGRkkwCgYI\nKoZIzj0EAwIDSAAwRQIhALluXWayFpylTOLCDIp925yn0rrtl77D/rM8AkOksTsE\nAiAEQ+w5pElSLFBINH/c0N1CgGN1snsdK1LRkUNjCk29Fg==\n-----END CERTIFICATE-----\n',
_publicKey: ECDSA_KEY { _key: [Object] },
_mspId: 'DfarmadminMSP',
_cryptoSuite:
CryptoSuite_ECDSA_AES {
_keySize: 256,
_hashAlgo: 'SHA2',
_cryptoKeyStore: [Object],
_curveName: 'secp256r1',
_ecdsaCurve: [Object],
_hashFunction: [Function],
_hashOutputSize: 32,
_ecdsa: [Object] } },
_signingIdentity:
SigningIdentity {
_certificate: '-----BEGIN CERTIFICATE-----\nMIIB/jCCAaSgAwIBAgIUdrt0WjnSmGsX1WuBWvXVTizqFKUwCgYIKoZIzj0EAwIw\nbzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xFzAVBgNVBAoTDmRmYXJtYWRtaW4uY29tMRowGAYDVQQDExFj\nYS5kZmFybWFkbWluLmNvbTAeFw0xOTA4MTQxMTEyMDBaFw0yMDA4MTMxMTE3MDBa\nMCExDzANBgNVBAsTBmNsaWVudDEOMAwGA1UEAxMFYWRtaW4wWTATBgcqhkjOPQIB\nBggqhkjOPQMBBwNCAARXptenPPGpVnJsEFv0wmJeybDYNoClJCyAv3GcRPb04WLR\nAynEoSXf+jwYIjypV98oeR127haGcDo7jHUn0DnBo2wwajAOBgNVHQ8BAf8EBAMC\nB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUW1YmLO6OaZB7FwXv6Gu7yc9jhNMw\nKwYDVR0jBCQwIoAgeD1bXE22u42++Y2v96xX+EKLzk8JkEcheGl5g8XGRkkwCgYI\nKoZIzj0EAwIDSAAwRQIhALluXWayFpylTOLCDIp925yn0rrtl77D/rM8AkOksTsE\nAiAEQ+w5pElSLFBINH/c0N1CgGN1snsdK1LRkUNjCk29Fg==\n-----END CERTIFICATE-----\n',
_publicKey: ECDSA_KEY { _key: [Object] },
_mspId: 'DfarmadminMSP',
_cryptoSuite:
CryptoSuite_ECDSA_AES {
_keySize: 256,
_hashAlgo: 'SHA2',
_cryptoKeyStore: [Object],
_curveName: 'secp256r1',
_ecdsaCurve: [Object],
_hashFunction: [Function],
_hashOutputSize: 32,
_ecdsa: [Object] },
_signer: Signer { _cryptoSuite: [Object], _key: [Object] } },
_mspId: 'DfarmadminMSP',
_cryptoSuite:
CryptoSuite_ECDSA_AES {
_keySize: 256,
_hashAlgo: 'SHA2',
_cryptoKeyStore:
CryptoKeyStore {
logger: [Object],
_store: [Object],
_storeConfig: [Object],
_getKeyStore: [Function] },
_curveName: 'secp256r1',
_ecdsaCurve:
PresetCurve {
curve: [Object],
g: <EC Point x: 6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 y: 4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5>,
n: <BN: ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551>,
hash: [Object] },
_hashFunction: [Function],
_hashOutputSize: 32,
_ecdsa:
EC {
curve: [Object],
n: <BN: ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551>,
nh: <BN: 7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8>,
g: <EC Point x: 6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 y: 4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5>,
hash: [Object] } } }
2019-08-14T11:17:28.526Z - error: [FabricCAClientService.js]: Failed to enroll 005, error:%o message=Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]], stack=Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]
at IncomingMessage.response.on (/vagrant/Dfarm-app/Node/node_modules/fabric-ca-client/lib/FabricCAClient.js:470:22)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
Failed to register user: Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]
Error: Authentication failure
It is clear that you are providing wrong credentials which means the wrong secret
For enrollment, we need ID & Secret
Double-check the secret and make sure that you have registered before proceeding for the enrolment
I suspect the issue is because you have a coding error (or error in your JSON :-)). The code is looking for userNamefield in an element, but your JSON array has a field username (lc). You could easily change your JSON to match.
If a user is to be enrolled for multiple times, you will need to specify maxEnrollments in the json of ca.register. Otherwise, ca.enroll will prompt { code: 20, message: 'Authentication failure'}.
For example, for registration you may have
var secret = await ca.register({
enrollmentID: userDetails[i].enrollmentID,
userName: userDetails[i].userName,
role: userDetails[i].role,
maxEnrollments: -1 // -1 means no limit on number of enrollments after registration
}, adminIdentity);
Related
I am trying to connect to a cluster using the last example from mongoose site
Here are my files using node14 and typescript
src/index.ts
import { APIGatewayProxyHandler } from "aws-lambda"
export { list as productsList } from "./products"
export const list: APIGatewayProxyHandler = (event, context, callback) => {
callback(null, {
statusCode: 200,
body: `Hello from ${process.env.AWS_SAM_BRANCH}`,
})
}
src/utils.ts
import mongoose from "mongoose"
import { APIGatewayProxyResult, Callback } from "aws-lambda"
let mongoConnection: Promise<typeof mongoose> | null = null
export const connectMongoose = async () => {
if (mongoConnection == null) {
const mongoURI = `mongodb+srv://USER:PASS#cluster0.ohjoj.mongodb.net/myFirstDB?retryWrites=true&w=majority`
mongoConnection = mongoose
.connect(mongoURI, { serverSelectionTimeoutMS: 3000 })
.then((mongooseReply) => {
console.log({ mongooseReply })
return mongoose
})
.catch((mongooseError) => {
console.log({ mongooseError })
return mongoose
})
await mongoConnection
}
return mongoConnection
}
export const errorHandler = (error: unknown, callback: Callback<APIGatewayProxyResult>) => {
console.error("catchedError", error)
if (error instanceof Error) {
callback(null, {
statusCode: 400,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ error: error.message }),
})
} else {
callback(null, {
statusCode: 500,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ error: "Internal server error" }),
})
}
}
src/products/index.ts
import { APIGatewayProxyHandler } from "aws-lambda"
import Model from "./model"
import { connectMongoose, errorHandler } from "../utils"
export const list: APIGatewayProxyHandler = (event, context, callback) => {
try {
connectMongoose()
Model.find({}, (error: unknown, reply: unknown) => {
if (error) throw error
callback(null, {
statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(reply),
})
})
} catch (error) {
errorHandler(error, callback)
}
}
src/products/model.ts
import mongoose from "mongoose"
const model = mongoose.model(
"Product",
new mongoose.Schema(
{
title: {
type: String,
required: true,
maxLength: 256,
},
description: {
type: String,
required: true,
maxLength: 2048,
},
count: {
type: Number,
required: true,
min: 0,
max: 1000 * 1000,
},
},
{
timestamps: true,
versionKey: false,
}
)
)
export default model
Here is the code in a repo is includes commands used to deploy with AWS SAM
https://github.com/LuisEnMarroquin/aws-sam-mongo
There are 2 routes in my app
https://2us58gl430.execute-api.us-east-2.amazonaws.com/
This works and returns Hello from test with status 200
https://2us58gl430.execute-api.us-east-2.amazonaws.com/products
This doesn't work and returns {"message":"Internal Server Error"} with status 500
Here are the CloudWatch logs exported as CSV
timestamp,message
1647203544609,"START RequestId: 83fd3fc8-1134-4ff4-a5f7-7e83a65159ce Version: $LATEST
"
1647203545742,"2022-03-13T20:32:25.685Z 83fd3fc8-1134-4ff4-a5f7-7e83a65159ce INFO {
mongooseReply: <ref *1> Mongoose {
connections: [ [NativeConnection] ],
models: { Product: Model { Product } },
events: EventEmitter {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
[Symbol(kCapture)]: false
},
options: {
pluralization: true,
autoIndex: true,
autoCreate: true,
[Symbol(mongoose:default)]: true
},
_pluralize: [Function: pluralize],
Schema: [Function: Schema] {
reserved: [Object: null prototype],
Types: [Object],
ObjectId: [Function]
},
model: [Function (anonymous)],
plugins: [ [Array], [Array], [Array], [Array], [Array], [Array] ],
default: [Circular *1],
mongoose: [Circular *1]
}
}
"
1647203549616,"END RequestId: 83fd3fc8-1134-4ff4-a5f7-7e83a65159ce
"
1647203549616,"REPORT RequestId: 83fd3fc8-1134-4ff4-a5f7-7e83a65159ce Duration: 5005.75 ms Billed Duration: 5000 ms Memory Size: 128 MB Max Memory Used: 76 MB Init Duration: 366.30 ms
"
1647203549616,"2022-03-13T20:32:29.616Z 83fd3fc8-1134-4ff4-a5f7-7e83a65159ce Task timed out after 5.01 seconds
"
As explained in this GitHub issue
A few suggestions:
You should either choose between a full callback approach and a full promise approach
Don't mix async / await with .then syntax when you can avoid it
import mongoose from "mongoose"
import { APIGatewayProxyHandler } from "aws-lambda"
let mongoConnection: Promise<typeof mongoose> | null = null
const connectMongoose = async () => {
if (mongoConnection == null) {
const mongoURI = `mongodb+srv://YOUR_CLUSTER_URL`
mongoConnection = mongoose
.connect(mongoURI, { serverSelectionTimeoutMS: 3000 })
.then((mongooseReply) => {
console.log({ mongooseReply })
return mongoose
})
.catch((mongooseError) => {
console.log({ mongooseError })
return mongoose
})
await mongoConnection
}
return mongoConnection
}
const Model = mongoose.model(
"Product",
new mongoose.Schema(
{
title: String,
description: String,
},
{
timestamps: true,
versionKey: false,
}
)
)
export const myRoute: APIGatewayProxyHandler = async (event, context) => {
try {
await connectMongoose();
const reply = await Model.find({}).exec();
return {
statusCode: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(reply),
};
} catch (error) {
return {
statusCode: 400,
headers: { "Content-Type": "application/json" },
body: "Server error",
};
}
}
I implemented node oidc Provider in my project and I got access_token also. but in access token in different format. how to change jwt token format and I added change access_token format to jwt but it could not work. How to resolve it this Issue and I need how to setup adapter config also.
Configuration.ts
const oidc = new Provider('http://localhost:3000', {
adapter:SequelizeAdapter,
clients: [
{
client_id: 'oidcCLIENT',
client_secret: '...',
grant_types: ['refresh_token', 'authorization_code'],
redirect_uris: ['http://sso-client.dev/providers/7/open_id', 'http://sso-client.dev/providers/8/open_id'],
}
],
interactions: {
url(ctx, interaction) { // eslint-disable-line no-unused-vars
return `/interaction/${interaction.uid}`;
},
},
cookies: {
keys: ['some secret key', 'and also the old rotated away some time ago', 'and one more'],
},
claims: {
address: ['address'],
email: ['email', 'email_verified'],
phone: ['phone_number', 'phone_number_verified'],
profile: ['birthdate', 'family_name', 'gender', 'given_name', 'locale', 'middle_name', 'name',
'nickname', 'picture', 'preferred_username', 'profile', 'updated_at', 'website', 'zoneinfo'],
},
format:{
AccessToken:'jwt'
},
features: {
devInteractions: { enabled: true }, // defaults to true
mTLS: {
enabled: true,
certificateBoundAccessTokens: true,
selfSignedTlsClientAuth: true,
getCertificate(ctx) {
return unescape(ctx.get('x-ssl-client-cert').replace(/\+/g, ' '));
},
certificateAuthorized(ctx) {
return ctx.get('x-ssl-client-verify') === 'SUCCESS';
},
certificateSubjectMatches(ctx, property, expected) {
if (property !== 'tls_client_auth_subject_dn') {
}
return ctx.get('x-ssl-client-s-dn') === expected;
},
},
claimsParameter: { enabled: true },
deviceFlow: { enabled: true },
dPoP: { enabled: true },
encryption: { enabled: true },
jwtUserinfo: { enabled: true },
introspection: { enabled: true },
registration: { enabled: true },
registrationManagement: { enabled: true, rotateRegistrationAccessToken: true },
jwtResponseModes: { enabled: true },
pushedAuthorizationRequests: { enabled: true },
requestObjects: {
request: true,
requestUri: true,
mode: 'strict',
},
// deviceFlow: { enabled: true }, // defaults to false
revocation: { enabled: true }, // defaults to false
userinfo: {enable:true}
},
findAccount: Account.findAccount,
issueRefreshToken: async (ctx, client, code) => {
return client.grantTypeAllowed('refresh_token') && (code.scopes.has('offline_access') || code.scopes.has('openid') || code.scopes.has('token'));
},
jwks: {
keys: [
{
d: 'VEZOsY07JTFzGTqv6cC2Y32vsfChind2I_TTuvV225_-0zrSej3XLRg8iE_u0-3GSgiGi4WImmTwmEgLo4Qp3uEcxCYbt4NMJC7fwT2i3dfRZjtZ4yJwFl0SIj8TgfQ8ptwZbFZUlcHGXZIr4nL8GXyQT0CK8wy4COfmymHrrUoyfZA154ql_OsoiupSUCRcKVvZj2JHL2KILsq_sh_l7g2dqAN8D7jYfJ58MkqlknBMa2-zi5I0-1JUOwztVNml_zGrp27UbEU60RqV3GHjoqwI6m01U7K0a8Q_SQAKYGqgepbAYOA-P4_TLl5KC4-WWBZu_rVfwgSENwWNEhw8oQ',
dp: 'E1Y-SN4bQqX7kP-bNgZ_gEv-pixJ5F_EGocHKfS56jtzRqQdTurrk4jIVpI-ZITA88lWAHxjD-OaoJUh9Jupd_lwD5Si80PyVxOMI2xaGQiF0lbKJfD38Sh8frRpgelZVaK_gm834B6SLfxKdNsP04DsJqGKktODF_fZeaGFPH0',
dq: 'F90JPxevQYOlAgEH0TUt1-3_hyxY6cfPRU2HQBaahyWrtCWpaOzenKZnvGFZdg-BuLVKjCchq3G_70OLE-XDP_ol0UTJmDTT-WyuJQdEMpt_WFF9yJGoeIu8yohfeLatU-67ukjghJ0s9CBzNE_LrGEV6Cup3FXywpSYZAV3iqc',
e: 'AQAB',
kty: 'RSA',
n: 'xwQ72P9z9OYshiQ-ntDYaPnnfwG6u9JAdLMZ5o0dmjlcyrvwQRdoFIKPnO65Q8mh6F_LDSxjxa2Yzo_wdjhbPZLjfUJXgCzm54cClXzT5twzo7lzoAfaJlkTsoZc2HFWqmcri0BuzmTFLZx2Q7wYBm0pXHmQKF0V-C1O6NWfd4mfBhbM-I1tHYSpAMgarSm22WDMDx-WWI7TEzy2QhaBVaENW9BKaKkJklocAZCxk18WhR0fckIGiWiSM5FcU1PY2jfGsTmX505Ub7P5Dz75Ygqrutd5tFrcqyPAtPTFDk8X1InxkkUwpP3nFU5o50DGhwQolGYKPGtQ-ZtmbOfcWQ',
p: '5wC6nY6Ev5FqcLPCqn9fC6R9KUuBej6NaAVOKW7GXiOJAq2WrileGKfMc9kIny20zW3uWkRLm-O-3Yzze1zFpxmqvsvCxZ5ERVZ6leiNXSu3tez71ZZwp0O9gys4knjrI-9w46l_vFuRtjL6XEeFfHEZFaNJpz-lcnb3w0okrbM',
q: '3I1qeEDslZFB8iNfpKAdWtz_Wzm6-jayT_V6aIvhvMj5mnU-Xpj75zLPQSGa9wunMlOoZW9w1wDO1FVuDhwzeOJaTm-Ds0MezeC4U6nVGyyDHb4CUA3ml2tzt4yLrqGYMT7XbADSvuWYADHw79OFjEi4T3s3tJymhaBvy1ulv8M',
qi: 'wSbXte9PcPtr788e713KHQ4waE26CzoXx-JNOgN0iqJMN6C4_XJEX-cSvCZDf4rh7xpXN6SGLVd5ibIyDJi7bbi5EQ5AXjazPbLBjRthcGXsIuZ3AtQyR0CEWNSdM7EyM5TRdyZQ9kftfz9nI03guW3iKKASETqX2vh0Z8XRjyU',
use: 'sig',
}, {
crv: 'P-256',
d: 'K9xfPv773dZR22TVUB80xouzdF7qCg5cWjPjkHyv7Ws',
kty: 'EC',
use: 'sig',
x: 'FWZ9rSkLt6Dx9E3pxLybhdM6xgR5obGsj5_pqmnz5J4',
y: '_n8G69C-A2Xl4xUW2lF0i8ZGZnk_KPYrhv4GbTGu5G4',
},
],
},
ttl: {
AccessToken: 24*60*60,//3600,
AuthorizationCode: 24*60*60,//600,
ClientCredentials: 24*60*60,//600,
DeviceCode: 24*60*60,//600,
IdToken: 24*60*60,//3600,
RefreshToken: 24*60*60,//1209600,
},
});
This is happening due to nod oidc provider version. With ver#7, instead of formats:{Access token:'jwt'} ( which worked perfectly in ver#6), you need to provide the resourceIndicators.
Follow this link to know more, Panva(Filip Skoken, author of the library) has given th detailed information.
Discussion on getting JWT token.:
https://github.com/panva/node-oidc-provider/discussions/959
Resource Indicators:
https://github.com/panva/node-oidc-provider/blob/main/docs/README.md#featuresresourceindicators
add the following methods under the features prop from config
resourceIndicators: {
defaultResource: (ctx, client, oneOf) => {
console.log('default resource', client);
return "http://example.com";
},
enabled: true,
getResourceServerInfo: (ctx, resourceIndicator, client) => {
console.log('get resource server info', client);
return ({
audience: 'solid',
accessTokenTTL: 2 * 60 * 60, // 2 hours
accessTokenFormat: 'jwt',
jwt: {
sign: { alg: 'ES256' },
},
});
},
useGrantedResource: (ctx, model) => {
// #param ctx - koa request context
// #param model - depending on the request's grant_type this can be either an AuthorizationCode, BackchannelAuthenticationRequest,
// RefreshToken, or DeviceCode model instance.
return true;
}
},
I am creating Express API and I am using Objection.js as ORM with Knex.js
I have created router for updating user password from the profile with 2 fields (old password and the new password),first it verifies the old password (protection from stealing JWT token). After it returns valid condition then I proceed to hash the new password with bcrypt and update it with .patch() otherwise it will return validation error the old password it is not the correct password. The problem is when I send the same exact request it goes through meaning that .patch not worked and did not save the new password to the database. Can anyone explain some solution to this problem or probably hit me with some documention on how to fix it
The code is bellow:
router.patch('/updatepassword', async (req, res, next) => {
const { id } = req.user;
const {
oldPassword,
newPassword,
} = req.body;
try {
await passwordSchema.validate({
oldPassword,
newPassword,
}, {
abortEarly: false
});
const UserOldPassword = await User.query().select('password').findById(id);
const validOldPassword = await bcrypt.compare(oldPassword, UserOldPassword.password);
if (validOldPassword) {
const hashedPassword = await bcrypt.hash(newPassword, 12);
const defi = User.query().patch({ password: hashedPassword }).where('id', id).returning('*')
.first();
console.log(defi);
res.status(200).json({
message: returnMessage.passwordUpdated
});
} else {
const error = new Error(returnMessage.invalidOldPassword);
res.status(403);
throw error;
}
} catch (error) {
next(error);
}
});
Console log:
QueryBuilder {
_modelClass: [Function: User],
_operations: [
UpdateOperation {
name: 'patch',
opt: [Object],
adderHookName: null,
parentOperation: null,
childOperations: [],
model: [User],
modelOptions: [Object]
},
KnexOperation {
name: 'where',
opt: {},
adderHookName: null,
parentOperation: null,
childOperations: [],
args: [Array]
},
ReturningOperation {
name: 'returning',
opt: {},
adderHookName: null,
parentOperation: null,
childOperations: [],
args: [Array]
},
FirstOperation {
name: 'first',
opt: {},
adderHookName: null,
parentOperation: null,
childOperations: []
}
],
_context: QueryBuilderContext {
userContext: QueryBuilderUserContext { [Symbol()]: [Circular] },
options: InternalOptions {
skipUndefined: false,
keepImplicitJoinProps: false,
isInternalQuery: false,
debug: false
},
knex: null,
aliasMap: null,
tableMap: null,
runBefore: [],
runAfter: [],
onBuild: []
},
_parentQuery: null,
_isPartialQuery: false,
_activeOperations: [],
_resultModelClass: null,
_explicitRejectValue: null,
_explicitResolveValue: null,
_modifiers: {},
_allowedGraphExpression: null,
_findOperationOptions: {},
_relatedQueryFor: null,
_findOperationFactory: [Function: findOperationFactory],
_insertOperationFactory: [Function: insertOperationFactory],
_updateOperationFactory: [Function: updateOperationFactory],
_patchOperationFactory: [Function: patchOperationFactory],
_relateOperationFactory: [Function: relateOperationFactory],
_unrelateOperationFactory: [Function: unrelateOperationFactory],
_deleteOperationFactory: [Function: deleteOperationFactory]
}
PATCH /v1/profile/updatepassword 200 1346.797 ms - 42
Solution: Do not forget to put await on async function.
So I was following this example to make a test with mongodb on jest, but after configuring everything I just get this when running jest:
If I remove globalSetup from jest.config.js, the tests appear although with errors because of mongo-enviroment and teardown configs been dependents on globalSetup:
If I run jest --debug I get this:
{
"configs": [
{
"automock": false,
"browser": false,
"cache": true,
"cacheDirectory": "/tmp/jest_rs",
"clearMocks": false,
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"detectLeaks": false,
"detectOpenHandles": false,
"errorOnDeprecated": false,
"filter": null,
"forceCoverageMatch": [],
"globals": {},
"haste": {
"providesModuleNodeModules": []
},
"moduleDirectories": [
"node_modules"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"node"
],
"moduleNameMapper": {},
"modulePathIgnorePatterns": [],
"name": "9f5155d702743ad8d949d6d219c1bc22",
"prettierPath": null,
"resetMocks": false,
"resetModules": false,
"resolver": null,
"restoreMocks": false,
"rootDir": "/home/mauricio/work/growthbond/gbnd1",
"roots": [
"/home/mauricio/work/growthbond/gbnd1"
],
"runner": "jest-runner",
"setupFiles": [
"/home/mauricio/work/growthbond/gbnd1/node_modules/regenerator-runtime/runtime.js"
],
"setupTestFrameworkScriptFile": "/home/mauricio/work/growthbond/gbnd1/testConfig/setupScript.js",
"skipFilter": false,
"snapshotSerializers": [],
"testEnvironment": "/home/mauricio/work/growthbond/gbnd1/testConfig/mongo-environment.js",
"testEnvironmentOptions": {},
"testLocationInResults": false,
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)+(spec|test).js?(x)"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"testRegex": "",
"testRunner": "/home/mauricio/work/growthbond/gbnd1/node_modules/jest-jasmine2/build/index.js",
"testURL": "http://localhost",
"timers": "real",
"transform": [
[
"^.+\\.jsx?$",
"/home/mauricio/work/growthbond/gbnd1/node_modules/babel-jest/build/index.js"
]
],
"transformIgnorePatterns": [
"/node_modules/"
],
"watchPathIgnorePatterns": []
}
],
"globalConfig": {
"bail": false,
"changedFilesWithAncestor": false,
"collectCoverage": false,
"collectCoverageFrom": null,
"coverageDirectory": "/home/mauricio/work/growthbond/gbnd1/coverage",
"coverageReporters": [
"json",
"text",
"lcov",
"clover"
],
"coverageThreshold": null,
"detectLeaks": false,
"detectOpenHandles": false,
"errorOnDeprecated": false,
"expand": false,
"filter": null,
"globalSetup": "/home/mauricio/work/growthbond/gbnd1/testConfig/setup.js",
"globalTeardown": "/home/mauricio/work/growthbond/gbnd1/testConfig/teardown.js",
"listTests": false,
"maxWorkers": 3,
"noStackTrace": false,
"nonFlagArgs": [],
"notify": false,
"notifyMode": "always",
"passWithNoTests": false,
"projects": null,
"rootDir": "/home/mauricio/work/growthbond/gbnd1",
"runTestsByPath": false,
"skipFilter": false,
"testFailureExitCode": 1,
"testPathPattern": "",
"testResultsProcessor": null,
"updateSnapshot": "new",
"useStderr": false,
"verbose": true,
"watch": false,
"watchman": true
},
"version": "23.6.0"
}
Note that
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)+(spec|test).js?(x)"
],
looks perfectly fine.
Related files
jest.config.js:
module.exports = {
globalSetup: './testConfig/setup.js',
globalTeardown: './testConfig/teardown.js',
testEnvironment: './testConfig/mongo-environment.js',
setupTestFrameworkScriptFile: './testConfig/setupScript.js',
verbose: true
}
setup.js (globalSetup):
const path = require('path');
const fs = require('fs');
const MongodbMemoryServer = require('mongodb-memory-server');
const globalConfigPath = path.join(__dirname, 'globalConfig.json');
const mongod = new MongodbMemoryServer.default({
instance: {
dbName: 'jest'
},
binary: {
version: '3.2.18'
},
autoStart: false,
});
module.exports = async () => {
if (!mongod.isRunning) {
await mongod.start();
}
const mongoConfig = {
mongoDBName: 'jest',
mongoUri: await mongod.getConnectionString()
};
// Write global config to disk because all tests run in different contexts.
fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig));
console.log('Config is written');
// Set reference to mongod in order to close the server during teardown.
global.__MONGOD__ = mongod;
process.env.MONGO_URL = mongoConfig.mongoUri;
};
teardown.js:
module.exports = async function() {
await global.__MONGOD__.stop();
};
mongo-environment.js:
const NodeEnvironment = require('jest-environment-node');
const path = require('path');
const fs = require('fs');
const globalConfigPath = path.join(__dirname, 'globalConfig.json');
module.exports = class MongoEnvironment extends NodeEnvironment {
constructor(config) {
super(config);
}
async setup() {
console.log('Setup MongoDB Test Environment');
const globalConfig = JSON.parse(fs.readFileSync(globalConfigPath, 'utf-8'));
this.global.__MONGO_URI__ = globalConfig.mongoUri;
this.global.__MONGO_DB_NAME__ = globalConfig.mongoDBName;
await super.setup();
}
async teardown() {
console.log('Teardown MongoDB Test Environment');
await super.teardown();
}
runScript(script) {
return super.runScript(script);
}
};
user.test.js (mongodb related test):
const MongoClient= require('mongodb');
const User = require('../../db/models/user');
let connection;
let db;
beforeAll(async () => {
connection = await MongoClient.connect(global.__MONGO_URI__);
db = await connection.db(global.__MONGO_DB_NAME__);
});
afterAll(async () => {
await connection.close();
await db.close();
});
describe('Password Encription', async () => {
const uEmail = 'test#a.com';
const uPass = '123test';
var testUser = new User({
email:uEmail ,
password: uPass
});
await testUser.save()
test('Encripted password string is different to plain password', async () => {
user = await User.findOne({ email: uEmail });
expect(user.password).not.toEqual(uPass);
});
test('ComparePassword method verify that plain password is the same that encrypted password', async () => {
rightPassword = await user.comparePassword(uPass);
expect(rightPassword).toBeTrue();
});
test('ComparePassword method verify that altered plain password is not the same that encrypted password', async () => {
wrongPassword = await user.comparePassword(uPass+'random');
expect(rightPassword).not.toBeTrue();
});
});
authService.test.js:
require('dotenv').config()
const authS = require('../../services/authService');
const jwt = require('jsonwebtoken');
describe('Auth Services',()=>{
const payload = {test:'This is a test'}
const user = {id:101}
const mockSecret = 'SECRET123HAAJAHJSoafdafda'
const token = authS.jwtSign(user,payload)
test('JWT sign', () => {
expect(authS.jwtSign(user,payload)).toBeString();
});
test('JWT verify different secret', ()=>{
badToken = jwt.sign(
payload,
mockSecret,
{ subject:String(user.id),
expiresIn:'1h'
}
);
expect(()=>authS.jwtVerify(badToken)).toThrowError(jwt.JsonWebTokenError)
})
test('JWT verify payload', ()=>{
expect(authS.jwtVerify(authS.jwtSign(user,payload))).toMatchObject(payload)
})
})
My environment:
node v11.0.0
jest 23.6.0
As a matter of fact I know that my test non mongodb related run if I comment
globalSetup: './testConfig/setup.js',
globalTeardown: './testConfig/teardown.js',
testEnvironment: './testConfig/mongo-environment.js',
from jest.config.js :
My problem was that I had another GlobalSetup file and they were conflicting. In my custom GlobalSetup I imported the #Shelf/jest-mongodb/setup and add it to mine.
const jestMongoSetup = require("#shelf/jest-mongodb/setup")
module.exports = async () => {
process.env.TZ = "UTC" //My config
await jestMongoSetup()
}
am tryind to add a service worker to my vuejs application. and this is what i get:
ServiceWorker registration failed: TypeError: Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script.
i have searching a lot but i can't figure out where the problem is.
the reason of adding a service worker is to save the Token of any device logged in the app and be able to send them notification.
in index.html : static/manifest.json">
// app.js
var config = {
apiKey: '',
authDomain: '',
databaseURL: '',
projectId: '',
storageBucket: '',
messagingSenderId: ''
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
let userToken = null,
isSubscribed = false
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register("firebase-messaging-sw.js", {scope: "firebase-cloud-messaging-push-scope"}).then(function (registration) {
const messaging = firebase.messaging();
messaging.useServiceWorker(registration);
}).catch(function (err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
})
} else {
}
});
messaging.requestPermission().then(function() {
//getToken(messaging);
return messaging.getToken();
}).then(function(token){
console.log(token);
})
.catch(function(err) {
console.log('Permission denied', err);
});
messaging.onMessage(function(payload){
console.log('onMessage: ',payload);
});
// firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
self.addEventListener('notificationclick', event => {
console.log(event)
event.notification.close()
event.waitUntil(
self.clients.openWindow('/')
)
})
var config = {
apiKey: '',
authDomain: '',
databaseURL: '',
projectId: '',
storageBucket: '',
messagingSenderId: ''
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
//manifest.json
{
"name": "Du",
"short_name": "Du",
"icons": [
{
"src": "/static/img/icons/cro-icon-64x64.png",
"sizes": "64x64",
"type": "image/png"
},
{
"src": "/static/img/icons/cro-icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
}
],
"start_url": "/",
"display": "fullscreen",
"orientation": "portrait",
"background_color": "#2196f3",
"theme_color": "#2196f3",
"gcm_sender_id": ""
}
console project folder console2