laugh =async()=> {
let mutation = gql`
mutation SignUp({$Email: String!
$Password: String!
}){
SignUp(data: {
Email: "tael32#gmil.com"
Password: "12345678"
}) {
User {
_id
Name
Rating
Photo
Badge
Email
}
Token
}}
`;
try {
let data = await client.mutate({mutation});
console.log('TCL: login -> data', data);
} catch (error) {
console.log('Majid', error);
}
}
when i call this function it generate error in code while it run correctly in post
mutation {
SignUp(data: {
Email: "chetanvirani#gmail.com"
Password: "12345678"
Name: "Chetan"
}) {
User {
_id
Name
Rating
Photo
Password
Badge
Email
}
Token
}
}
here the code which run in postman but not in a code,i don't know what was was the error in my code
Curly braces specify a selection set. There's no reason to wrap your variable definitions in curly braces:
mutation SignUp($Email: String!, $Password: String!) {
...
}
Related
I'm trying to wrap my head around mobx-state-tree and whipped up a simple currentUserStore to hold some data for a logged in user and allow login/logout:
import { types } from "mobx-state-tree";
import { client } from '../../../helpers/client';
const User = types
.model("User", {
name: types.string,
email: types.string,
type: types.string,
token: types.string,
roles: types.array(types.string),
})
export const CurrentUserStore = types
.model("CurrentUserStore", {
user: types.optional(types.maybeNull(User), () => null)
})
.actions((currentUserStore) => ({
async login(login, password) {
const result = await client.post(`auth`, {
email: login,
password,
});
const { name, email, type, token, roles } = result
currentUserStore.user = User.create({ name, email, type, token, roles })
localStorage.setItem('authUser', JSON.stringify(result));
},
logout() {
currentUserStore.user = null
localStorage.removeItem('authUser')
},
}));
When calling the login function, I get the error Cannot modify 'CurrentUserStore#/currentUserStore', the object is protected and can only be modified by using an action.. There's something I'm missing here, but not exactly sure why I shouldn't be able to do something like this after reading through example where the store is modified directly in an action like this.
Once I moved the modification out of an async func, it worked. Just changed to this:
async login(login, password) {
const result = await client.post(`auth`, {
email: login,
password,
});
this.setUser(User.create(result))
localStorage.setItem('authUser', JSON.stringify(result));
},
logout() {
currentUserStore.user = null
localStorage.removeItem('authUser')
},
setUser(user) {
self.user = user
}
I get this error message when I try to test the /api/register end point with Postman and following POST request:
{
"name" : "first",
"email" : "first#one.com",
"password" : "123"
}
[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'name')
request: { url: "http://0.0.0.0:8000/api/register", method: "POST", hasBody: true }
response: { status: 404, type: undefined, hasBody: false, writable: true }
at register (file:///C:/Users/m/app_back/controllers/auth_controller.ts:9:22)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async EventTarget.#handleRequest (https://deno.land/x/oak#v9.0.1/application.ts:379:9)
TypeError: Cannot read properties of undefined (reading 'name')
at register (file:///C:/Users/m/app_back/controllers/auth_controller.ts:9:22)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async EventTarget.#handleRequest (https://deno.land/x/oak#v9.0.1/application.ts:379:9)
This is my auth_controller.ts file:
import {
create, verify, decode, getNumericDate, RouterContext, hashSync, compareSync
} from "../deps.ts";
import { userCollection } from "../mongo.ts";
import User from "../models/user.ts";
export class AuthController {
async register(ctx: RouterContext) {
const { value: { name, email, password } } = await ctx.request.body().value;
let user = await User.findOne({ email });
if (user) {
ctx.response.status = 422;
ctx.response.body = { message: "Email is already used" };
return;
}
const hashedPassword = hashSync(password);
user = new User({ name, email, password: hashedPassword });
await user.save();
ctx.response.status = 201;
ctx.response.body = {
id: user.id,
name: user.name,
email: user.email
};
}
async login(ctx: RouterContext) {
const { value: { email, password } } = await ctx.request.body().value;
if (!email || !password) {
ctx.response.status = 422;
ctx.response.body = { message: "Please provide email and password" };
return;
}
let user = await User.findOne({ email });
if (!user) {
ctx.response.status = 422;
ctx.response.body = { message: "Incorrect email" };
return;
}
if (!compareSync(password, user.password)) {
ctx.response.status = 422;
ctx.response.body = { message: "Incorrect password" };
return;
}
const key = await crypto.subtle.generateKey(
{ name: "HMAC", hash: "SHA-512" },
true,
["sign", "verify"],
);
const jwt = create( {
alg: "HS256",
typ: "JWT",
}, {
iss: user.email,
exp: getNumericDate(
Date.now() + parseInt(Deno.env.get("JWT_EXP_DURATION") || "0"))
},
key
);
ctx.response.body = {
id: user.id,
name: user.name,
email: user.email,
jwt,
};
}
}
export default new AuthController();
What is the problem and how can I resolve it?
EDIT: I added this line to the code:
console.log( await ctx.request.body().value );
And this is the result:
{ name: "first", email: "first#one.com", password: "123" }
You are facing this issue because you are trying to access ctx.request.body().value.value.name (notice multiple value porperties). You could change line 9 of your auth_controller.ts to this to fix it:
const { name, email, password } = await ctx.request.body().value;
On a side note, I also noticed few more issues with your current code.
Your JWT algorithm and generated secret key encryption algorithm should match
So either change your hash encryption on line 47 to SHA-256 or your JWT algorithm on line 53 to HS512.
You don't need to pass current date to getNumericDate function
This helper function already does this job for you, all you need to pass here is the time period (in seconds) when you want your token to expire. In your case it would be:
getNumericDate(Deno.env.get("JWT_EXP_DURATION") || 0)}
i'm reciving the error Variable "$id" of required type "String!" was not provided. Someone knows why?
In my backend (node-mongo-graphql)
Mutation:
type Mutation {
deleteAmbiente(_id: String!): Ambiente
}
Resolver:
async deleteAmbiente(_,_id, context) {
console.log("hi there!", _id)
}
In my front-end (vue + apollo)
async deleteAmbiente() {
try {
let id = this.item._id
const res = await apolloClient.mutate({
mutation: ELIMINAR_AMBIENTE,
variables: id, // id has a value, if i send "hello" from here, it doesn't work either
});
console.log(res)
} catch (err) {
err;
}
},
export const ELIMINAR_AMBIENTE = gql`
mutation deleteAmbiente(
$id: String!
){
deleteAmbiente(_id:$id){
nombre
}
}
`
Apollo-client's query:
apolloClient
.query({
query: authQuery,
variables: {
login: payload.login,
password: payload.password,
},
})
.then((res) => console.log(res)
Contents of authQuery (it's inside a file.gql):
query auth {
data
}
i always get the following response:
{
data: null
loading: false
networkStatus: 7
stale: true
}
Though in graphiQL i am getting correct response:
Query in a GraphiQL
{
auth(login:"root#admin", password:"1234")
}
And response:
{
"data": {
"auth": "eyJhbGciOi8"
}
}
I suspect my file.gql is the culprit? Or variables inside query not being read?
I had to wrap my query this way:
query Auth($login: String!, $password: String!) {
auth (login: $login, password: $password)
}
When you're using params with your Query, you always have to wrap it this way.
Using this vue.js method to login users:
loginUser: function () {
socket.emit('loginUser', {
email: this.email ,
password: this.password
}, function() {
console.log('rooms in callback are:', rooms);
});
}
On the server the loginUser event is handled by:
socket.on('loginUser', (newuser,callback)=> {
var body = _.pick(newuser, ['email', 'password']);
console.log('body is:', body);
User.findByCredentials(body.email, body.password).then((user) => {
return user.generateAuthToken().then((token) => {
if (token) {
console.log('token was found');
let rooms = ['Cats', 'Dogs', 'Birds'];
callback(rooms);
} else {
socket.emit('loginFailure', {'msg' : 'Login failure'});
}
}).catch((e) => {
throw e;
});
}).catch((e) => {
socket.emit('loginFailure', {'msg' : 'Login failure'});
throw e;
});
});
I can see 'token was found' printed out in the console but does not recieve the rooms being printed in the browser console. I receive no errors either.
I'm wondering whetehr it is due to how vue.js methods work? And if so, if there is a way around it?
You forgot to specify rooms as argument in the callback
loginUser: function () {
socket.emit('loginUser', {
email: this.email ,
password: this.password
}, function(rooms) { // need to have rooms argument
console.log('rooms in callback are:', rooms);
});
}