I have changed both files as far as commas and semicolons, both of which have been driving eslint crazy. Nothing seems to appease it within factory.js especially, but the odd error messages that I am getting below make me think this may be something else. Anyone have any experience with this?
UserSeeder.js
const Factory = use('Factory');
const Database = use('Database');
class UserSeeder {
async run () {
const user = await Factory
.model('App/Models/User')
.create()
const users = await Database.table('users');
console.log(users);
}
}
module.exports = UserSeeder;
factory.js
const Factory = use('Factory');
const Hash = use('Hash');
Factory.blueprint('App/Models/User', () => {
return {
username: 'test',
email: 'test#test.com',
password: await Hash.make('test'),
}
});
And the lovely and informative error message:
SyntaxError: Unexpected identifier
1 _preLoadFiles.forEach
D:\Source\VuePractice\intro-to-vuetify-with-
adonis\server\node_modules\#adonisjs\ignitor\src\Ignitor\index.js:375
2 Ignitor._loadPreLoadFiles
D:\Source\VuePractice\intro-to-vuetify-with-
adonis\server\node_modules\#adonisjs\ignitor\src\Ignitor\index.js:367
3 Ignitor.fire
D:\Source\VuePractice\intro-to-vuetify-with-
adonis\server\node_modules\#adonisjs\ignitor\src\Ignitor\index.js:760
The issue you have in your code is that you are using the keyword await in your Factory for App/Models/User and the callback isn't async.
It needs to be:
const Hash = use('Hash')
const Factory = use('Factory')
Factory.blueprint('App/Models/User', async () => {
return {
username: 'test',
email: 'test#test.com',
password: await Hash.make('test'),
}
})
In my case it was just a typo that I had in my start/routes.js file.
It gave me the next error.
And i solved it removing the extra character. I hope it helps anyone with the same error.
Related
I'm trying to create a jest test for the below method. And I got errors for two scenarios.
So basically in checkKioskUserPhone method,
Find the user by the phone number( commonService.findKioskUserByPhone)
In findKioskUserByPhone method, we are gonna find the user by the phone number and send error messages if it's unregistered or already registered.
And then return user.
(back to checkKioskUserPhone) if the user doesn't have auth code and pin number we are gonna send him/her auth code and return jwt, and etc.
async checkKioskUserPhone(kioskLoginDto: KioskLoginDto): Promise<ResponseDto<UserAuthDto>> {
const user = await this.commonService.findKioskUserByPhone(kioskLoginDto);
const isConfirmedAuthCode = user.authCode === 'OK' ? true : false;
const isSetPin = user.pin ? true : false;
if (!isConfirmedAuthCode && !isSetPin) {
await this.userService.authenticatePhone(user.id, Builder(AuthorizePhoneDto).phone(user.phone).build());
}
const jwtInfo = await this.createToken(this.removeCredentialField(user));
return Builder<ResponseDto<UserAuthDto>>(ResponseDto)
.result(Builder(UserAuthDto).isConfirmedAuthCode(isConfirmedAuthCode).isSetPin(isSetPin).jwtInfo(jwtInfo).build())
.build();
}
async findKioskUserByPhone(kioskLoginDto: KioskLoginDto): Promise<User> {
const user = await this.userService.findOne({ where: { phone: kioskLoginDto.phone } });
// throw Error message when unregistered phone attempt to login
if (!user) {
throw new NotFoundException('User not found');
}
// throw Error message when registered phone by whatsapp attempt to login
if (user.provider !== Provider.KIOSK) {
throw new ConflictException('You are already joined by Whatsapp.');
}
return user;
}
Jest code
it('when unregistered phone attempt to login', async () => {
const phone = '2212223333';
const kioskLoginDto = Builder(KioskLoginDto).phone(phone).build();
service.commonService.findKioskUserByPhone = jest.fn().mockResolvedValue(null);
try {
await service.checkKioskUserPhone(kioskLoginDto);
expect('here').not.toBe('here');
} catch (error) {
expect(error).toBeInstanceOf(NotFoundException);
expect(error.message).toContain('User not found');
}
});
it('When registered phone by app attempt to login', async () => {
const phone = '2212223333';
const kioskLoginDto = Builder(KioskLoginDto).phone(phone).build();
const user = Builder(User).phone(phone).provider(Provider.WHATSAPP).build();
service.commonService.findKioskUserByPhone = jest.fn().mockResolvedValue(user);
try {
await service.checkKioskUserPhone(kioskLoginDto);
expect('here').not.toBe('here');
} catch (error) {
expect(error).toBeInstanceOf(ConflictException);
expect(error.message).toContain('You are already joined by Whatsapp.');
}
});
Jest Error screenshot
you're overriding the findKioskUserByPhone method to just return null:
service.commonService.findKioskUserByPhone = jest.fn().mockResolvedValue(null);
so findKioskUserByPhone simply is never running, a mock function is just returning null, and is thus never throwing the error you expect. instead, here:
const user = await this.commonService.findKioskUserByPhone(kioskLoginDto);
user is getting set to null and here:
const isConfirmedAuthCode = user.authCode === 'OK' ? true : false;
you're trying access some authCode property of null, which throws the TypeError you're getting.
you probably meant to override the findOne method on the user service:
service.userService.findOne = jest.fn().mockResolvedValue(null);
so the error you want will actually throw in findKioskUserByPhone
(note I don't know if this is actually where you have the user service to provide the mock, I'm just assuming)
I am writing unit test for my auth.service module validateReader unit,
async validateReader(username: string, password: string): Promise<any> {
const reader = await this.readerService.findOne(username);
const match = await bcrypt.compare(password, reader.password);
if (match) {
const { password, ...result } = reader.toJSON();
this.logger.info(
`Reader ${reader.username} username & password validation passed`,
);
return result;
}
this.logger.warn(`Incorrect password in reader ${reader.username} login`);
return null;
}
I tried to mock readerService.findOne function as following:
jest
.spyOn(readerService, 'findOne')
.mockImplementationOnce(() => Promise.resolve(readerStub()));
but did not work, always got error - Cannot spy the findOne property because it is not a function; I think the reason is the returned value must be mongoose document object (need toJSON() method), but my readerStub() just return a reader object, missing lots of document properties. Is there anyway I can set up stub for document & reader? And maybe my analysis is wrong, there is other reason to got this error.
Following is my mock readerService:
export const ReaderService = jest.fn().mockReturnValue({
register: jest.fn().mockResolvedValue(readerStub()),
findOne: jest.fn().mockResolvedValue(readerStub()),
getProfile: jest.fn().mockResolvedValue(readerStub()),
updateProfile: jest.fn().mockResolvedValue(readerStub()._id),
changePwd: jest.fn().mockResolvedValue(readerStub().username),
login: jest.fn().mockResolvedValue(accessTokenStub()),
tokenRefresh: jest.fn().mockReturnValue(accessTokenStub()),
logout: jest.fn().mockResolvedValue(readerStub()._id),
});
We use unmanaged transactions in many cases but this issue only occurs in 2 functions which are invoked more commonly and only on production environment (Haven't been able to reproduce it on dev).
Our code looks similar to this:
const t = await database.t();
try {
await function1(..., {t});
await function2(..., {t});
}
catch (e) {
await t.rollback(); <- This throws the error
throw e
};
// more logic
await t.commit();
Where database is just a Sequelize instantiation with name of database, username and password.
We assumed it's a connection error according to this: https://github.com/sequelize/sequelize/issues/4850 but in this case code wouldn't reach beyond line one on our pseudocode.
Error output on CloudWatch:
If you have multiple try-catch then maybe need to check the transaction state before rollback/commit:
const t = await database.t();
try {
await function1(..., { t });
await function2(..., { t });
}
catch (e) {
if (!t.finished) {
await t.rollback();
}
throw e;
};
// more logic
await t.commit();
Reference links:
https://github.com/sequelize/sequelize/issues/6547#issuecomment-466016971
https://github.com/sequelize/sequelize/pull/5043/files#diff-6c5ddfc7d68c447e32ef4c38b7ed69628910355ea0aff735bd4bcecc1256a8d8
I tried to use polkadot-js libray to run a simple app for transferring tokens between Dusty accounts on plasm. Source code and package.json for running the snippet is found on this git repo
Node version: v12.8.2
Yarn version: 1.22.5
const { ApiPromise, WsProvider } = require('#polkadot/api')
const { Keyring } = require('#polkadot/keyring')
const plasmDefinitions = require('#plasm/types/interfaces/definitions');
const jsonDefinitions = require('./types.js')
const fs = require('fs')
const BN = require('bn.js')
startChain()
async function startChain() {
console.log("trying connection to ", process.env.RPC_URL)
const targetAddress = process.env.TARGET_ADDRESS
const provider = new WsProvider(process.env.RPC_URL)
const types = Object.values(plasmDefinitions).reduce(
(res, { types }) => ({ ...res, ...types }),
{},
);
const api = new ApiPromise({
provider,
types
});
api.on('connected', () => console.log(`Connected to ${process.env.RPC_URL}`));
api.on('disconnected', () => console.log(`Disconnected from ${process.env.RPC_URL}`));
await api.isReady;
const [chain, nodeName, nodeVersion] = await Promise.all([
api.rpc.system.chain(),
api.rpc.system.name(),
api.rpc.system.version()
])
console.log(`You are connected to chain ${chain} using ${nodeName} v${nodeVersion} - ${process.env.RPC_URL}`)
const keyring = new Keyring({ type: 'sr25519' })
const fromPair = keyring.addFromUri(process.env.PLASM_MNEMONIC)
const fromAmountUnits = new BN('1000000000000000')
const transfer = api.tx.balances.transfer(targetAddress, fromAmountUnits)
// send value
//const nonce = await api.query.system.accountNonce(process.env.FROM_ADDRESS)
const nonce = await api.rpc.system.accountNextIndex(process.env.FROM_ADDRESS)
console.log("got nonce", nonce)
const txHash = await transfer.signAndSend(fromPair, {nonce})
}
Stack trace:
trying connection to wss://rpc.dusty.plasmnet.io/ Connected to wss://rpc.dusty.plasmnet.io/ You are connected to chain Dusty using Plasm Node v1.6.1-cf15b11-x86_64-linux-gnu - wss://rpc.dusty.plasmnet.io/ got nonce Type { negative: 0, words: [ 0 ], length: 1, red: null, registry: TypeRegistry {} } 2021-02-05 21:00:27 RPC-CORE: submitExtrinsic(extrinsic: Extrinsic): Hash:: 1002: Verification Error: Execution: Could not convert parameter txbetween node and runtime: Error decoding field CheckMortality.0: RuntimeApi, Execution: Could not convert parametertxbetween node and runtime: Error decoding field CheckMortality.0 (node:13572) UnhandledPromiseRejectionWarning: Error: 1002: Verification Error: Execution: Could not convert parametertxbetween node and runtime: Error decoding field CheckMortality.0: RuntimeApi, Execution: Could not convert parametertxbetween node and runtime: Error decoding field CheckMortality.0 at RpcCoder._checkError (<mydir>\examples\plasm-simple-transfer\node_modules\#polkadot\api\node_modules\#polkadot\rpc-provider\coder\index.js:84:13) at RpcCoder.decodeResponse (<mydir>\examples\plasm-simple-transfer\node_modules\#polkadot\api\node_modules\#polkadot\rpc-provider\coder\index.js:47:10) at WsProvider.value (<mydir>\examples\plasm-simple-transfer\node_modules\#polkadot\api\node_modules\#polkadot\rpc-provider\ws\index.js:214:90) at W3CWebSocket.value [as onmessage] (<mydir>\examples\plasm-simple-transfer\node_modules\#polkadot\api\node_modules\#polkadot\rpc-provider\ws\index.js:194:153) at W3CWebSocket._dispatchEvent [as dispatchEvent] (<mydir>\examples\plasm-simple-transfer\node_modules\yaeti\lib\EventTarget.js:107:17) at W3CWebSocket.onMessage (<mydir>\examples\plasm-simple-transfer\node_modules\websocket\lib\W3CWebSocket.js:234:14) at WebSocketConnection.<anonymous> (<mydir>\examples\plasm-simple-transfer\node_modules\websocket\lib\W3CWebSocket.js:205:19) at WebSocketConnection.emit (events.js:315:20) at WebSocketConnection.processFrame (<mydir>\examples\plasm-simple-transfer\node_modules\websocket\lib\WebSocketConnection.js:554:26) at <mydir>\examples\plasm-simple-transfer\node_modules\websocket\lib\WebSocketConnection.js:323:40 (node:13572) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag--unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:13572) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Additionally when i try to do a clear run (delete node_modules and reinstall) i get the same message but with field CheckMortality replaced by CheckNonce. Fields returned by plasm-types library can be found in this file in json format.
I tried to figure it out what types are wrong by going through node templates respositories, but i couldnt figure it out. How can it be fixed?
I had to do a small change to type definitions to circumvent the problem. In other words replace:
const types = Object.values(plasmDefinitions).reduce(
(res, { types }) => ({ ...res, ...types }),
{},
);
const api = new ApiPromise({
provider,
types
});
for
const types = Object.values(plasmDefinitions).reduce(
(res, { types }) => ({ ...res, ...types }),
{},
);
types["Address"] = "IndicesLookupSource";
types["LookupSource"] = "IndicesLookupSource";
const api = await ApiPromise.create({
provider: provider,
types: types
});
More information about this issue can be found here and here
I'm having a problem with my adding MFA to my site which manages authentication with AWS Amplify.
I've followed the example here and created the code below to handle both users who have MFA enabled, and those that don't.
const Signin = props => {
const { classes, onStateChange, history } = props;
const [inputs, setInputs] = useState({
username: '',
password: '',
});
const [currentStep, setCurrentStep] = useState(1)
const [userObject, setUserObject] = useState({})
const [authCode, setauthCode] = useState({code: ''})
const onSignIn = async (e) => {
const username = inputs.username.toLowerCase()
await Auth.signIn({
username, // Required, the username
password: inputs.password, // Optional, the password
}).then(user => {
if (user.preferredMFA === 'SOFTWARE_TOKEN_MFA'){
setUserObject(user)
setCurrentStep(2)}
else{
onStateChange('signedIn', {})
history.push('/dashboard');
}
})
.catch(err => {
showAlert(err.message)
if (err.code === 'PasswordResetRequiredException') {
onStateChange('forgotPassword')
history.push('/forgotpassword');
}
})
}
const MfaSignIn = async (e) => {
const user=userObject
await Auth.confirmSignIn(
user,
authCode.code,
user.preferredMFA
).then(user => {
onStateChange('signedIn', {})
history.push('/dashboard');
})
.catch(err => {
showAlert(err.message)
if (err.code === 'PasswordResetRequiredException') {
onStateChange('forgotPassword')
history.push('/forgotpassword');
}
})
If MFA is not enabled the login page will call the onSignIn function then log them in. If MFA is enabled the user object returned from the signin function will return the value "SOFTWARE_TOKEN_MFA" for the preferredMFA key, and a second page will load which allows the user to enter their MFA code, which is handled by the MfaSignIn function.
No MFA works fine, however when attempting to use the MfaSignIn function as is I get "Missing required parameter Session"
the Session key of the user object returned by onSignIn has a value of null, and there's no mention of it needing to be added from the docs. Ive tried adjusting this function to
const MfaSignIn = async (e) => {
e.preventDefault(authCode.code);
const session= Auth.currentSession().then(data=> {return data})
const token = await session.then(data=>{return data.getAccessToken()})
const user=userObject
user.Session=token.jwtToken
await Auth.confirmSignIn(
user,
authCode.code,
user.preferredMFA
).then(user => {
onStateChange('signedIn', {})
history.push('/dashboard');
})
.catch(err => {
showAlert(err.message)
if (err.code === 'PasswordResetRequiredException') {
onStateChange('forgotPassword')
history.push('/upgrade');
}
})
}
Where I call the Auth.currentSession method and add the data from there to the Session value in the user object. Adding the whole object returns the error-
"Start of structure or map found where not expected."
- seems to need a string not a map object
I've tried adding each of the three JWT token strings that are found in the currentSession object, along with the result of the getAccessToken as in the example above. All return the error
"Invalid session provided"
I'm at a loss at what I need to give the Auth.confirmSignIn to let the user sign in- I appear to be doing everything correctly as per the docs.
Any ideas?