Strapi how query relationship in CRON - strapi

I'm trying to write a CRON in strapi to query product that is post_status: "Draft" and username blocked is false. If true, it should not show and results.
The username has a one to many relations with the product.
"use strict";
module.exports = {
"*/1 * * * *": async () => {
const draftProductToPublishToFacebook = await strapi.api.product.services.product.find(
{
post_status: "Draft",
published_at_lt: new Date(),
username: {
blocked: false,
},
}
);
},
};
Sample data
{
post_status: 'Draft',
_id: 5eef02af7761f1425dd0ccec,
stock_status: 'test',
product_status: 'publish',
__v: 0,
username: {
confirmed: true,
blocked: false,
_id: 5eef05985f864742725ab8e1,
username: 'test2',
email: 'test2#test.com',
provider: 'local',
createdAt: 2020-06-21T07:00:40.996Z,
updatedAt: 2020-07-17T01:24:58.918Z,
__v: 0,
role: 5ee30d5424f89d5253877e90,
id: '5eef05985f864742725ab8e1'
},
published_at: 2020-08-02T00:20:00.000Z,
id: '5eef02af7761f1425dd0ccec'
}
The error I'm getting
(node:3652) UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "{ blocked: false }" at path "username" for model "product"
Thanks

'username.blocked': false
should work.

Related

Next.js and AWS Amplify getting Error: No Current User - getServerSideProps

getServerSideProps is displaying "No Current User", but I'm logged in my app.
type Post
#model
#key(
name: "postsByUsername"
fields: ["username"]
queryField: "postsByUsername"
)
#auth(
rules: [
{ allow: owner, ownerField: "username" }
{ allow: private, operations: [read] }
{ allow: public, operations: [read] }
]
) {
id: ID!
username: String
image: S3Object
}
I'm able to use AWS AppSync's website to actually query the posts by username, it returned values. I logged in using the same login I'm in for my app.
export async function getServerSideProps() {
const SSR = withSSRContext();
const { data } = await SSR.API.graphql({
query: postsByUsername,
variables: {
username: "username" // checked in dynamodb, same username as signed in.
},
authMode: "AMAZON_COGNITO_USER_POOLS",
});
return {
props: {
posts: data.postsByUsername.items,
},
};
}
I've also added ssr in my _app.js:
import { Amplify } from "aws-amplify";
import awsExports from "../../aws-exports";
Amplify.configure({ ...awsExports, ssr: true });
in aws-exports.js:
const awsmobile = {
"aws_project_region": "xxxxx",
"aws_appsync_graphqlEndpoint": "https://...",
"aws_appsync_region": "xxxxx",
"aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
"aws_appsync_apiKey": "xxx-xxxxxxxx...",
"aws_cognito_identity_pool_id": "xxxxxx",
"aws_cognito_region": "xxxxx",
"aws_user_pools_id": "xxxxx",
"aws_user_pools_web_client_id": "xxxxxx",
"oauth": {},
"aws_user_files_s3_bucket": "xxxxxx",
"aws_user_files_s3_bucket_region": "xxxxxx"
};
everything in awsmobile were autogenerated.
You need to pass through the request context in your withSSRContext function, so your getServerSideProps function should look as follows
export async function getServerSideProps({ req }) {
const SSR = withSSRContext({ req });
...
}
Reference:
https://docs.amplify.aws/lib/ssr/q/platform/js/#withssrcontext

I can't access $auth.user from auth plugin or middleware using nuxtjs and getting api from laravel

My goal is that i want to access $auth.user.roles from plugin and middleware to be able to not let this role reach the other role page.
what is expected is that when console.log($auth.user) it gives me the user data (id,...) and when a console.log($auth.loggedIn)it gives me true.
My problem is that i can't access $auth.user from plugin and middleware to chieve that which $auth.user = null and $auth.loggedIn = false while im logged in.
here is my nuxt.config.js:
axios: {
baseURL: env.parsed.API_URL || 'http://localhost:3000/api',
debug:true},
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/auth/signin',
method: 'post',
propertyName: 'data.token'
},
user: {
url: '/auth/me',
method: 'get',
propertyName: 'data'
},
logout: {
url: '/auth/signout',
method: 'post'
},
tokenRequired: true,
tokenType: 'bearer',
globalToken: true,
autoFetchUser: true
},
},
},
redirect:false,
plugins: [ '~/plugins/roles.js' ]
},
here is my plugins/roles.js :
export default function ({app}) {
const username = app.$auth.user
if (!app.$auth.loggedIn) {
return console.log(username ,'roles plugin ', app.$auth.loggedIn)
}}
here is the res: null roles plugin false
the same result using this code:
export default function ({$auth}) {
const username = $auth.user
if (!app.$auth.loggedIn) {
return console.log(username ,'roles plugin', $auth.loggedIn)
}}
Ps:when i use $auth.user in my vue pages it gives me the whole user data (thats wonderfull)
I searched about this problem so i found common answers like :
*Change the user propertyName to false.
*reinstall node_modules.
but same result
Thank you every one <3

Is there a way to add conversation history when connecting to direct line?

We are using botframework-webchat v4. Is there any way to provide history that will be shown up in the chat?
This is currently what I have, but its not working, not sure what format should be for activities in store.
const store = window.WebChat.createStore(
{
activities: ['{"type":"message",...}']
},
({ dispatch }: { dispatch: any }) => (next: any) => (action: any) => {
if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
const { activity } = action.payload;
if (activity.type === 'event' && activity.name === 'sample:backchannel') {
alert(JSON.stringify(activity, null, 2));
}
}
return next(action);
}
)
window.WebChat.renderWebChat(
{
directLine: this.directLine,
userID: this.userId,
styleOptions,
store
},
this.botWindowElement.nativeElement
);
Thanks in advance!!
You're solution above will, technically, work. Although, it's not very scalable in the long run. I would recommend you look over this BotFramework-WebChat experimental sample, Conversation History. It utilizes the sendConversationHistory API. This sample is a bit on the complex side, but will do precisely what you are wanting, i.e. load a previous user's conversation when a new session is started.
If you are wanting to reconnect a previous conversation (meaning continue a conversation using the same conversationId) then you should be aware that the Direct Line service has certain limitations. Reconnecting will only work for up to 14 days after the last activity to that conversation and only 24 hours if activities are present.
Hope of help!
#StevenKanberg Thanks for the help!
I found the answer in source code of BotFramework-WebChat.
Here is the sample,
test('absolute timestamp', async () => {
const activities = [
{
type: 'message',
id: '6266x5ZXhXkBfuIH0fNx0h-o|0000000',
timestamp: '2019-08-08T16:41:12.9397263Z',
from: {
id: 'dl_654b35e09ab4149595a70aa6f1af6f50',
name: '',
role: 'user'
},
textFormat: 'plain',
text: 'echo "Hello, World!"'
},
{
type: 'message',
id: '6266x5ZXhXkBfuIH0fNx0h-o|0000001',
timestamp: '2019-08-08T16:41:13.1835518Z',
from: {
id: 'webchat-mockbot',
name: 'webchat-mockbot',
role: 'bot'
},
text: 'Echoing back in a separate activity.'
},
{
type: 'message',
id: '6266x5ZXhXkBfuIH0fNx0h-o|0000002',
timestamp: '2019-08-08T16:41:13.3963019Z',
from: {
id: 'webchat-mockbot',
name: 'webchat-mockbot',
role: 'bot'
},
text: 'Hello, World!'
}
];
const styleOptions = { timestampFormat: 'absolute' };
const { driver } = await setupWebDriver({ storeInitialState: { activities }, props: { styleOptions } });

JSON schema validation with perfect messages

I have divided the data entry in a REST call in 4 parts. Data can be sent to REST call via:-
headers
query params
path params
request body
So in order to validate the presence of any key in any of the above 4 parts I have created a schema in this format. So if in case I have to validate anything in query params I will add the key 'query' and then add the fields inside that, that needs to be validated
const schema = {
id: 'Users_login_post',
type: 'object',
additionalProperties: false,
properties: {
headers: {
type: 'object',
additionalProperties: false,
properties: {
Authorization: {
type: 'string',
minLength: 10,
description: 'Bearer token of the user.',
errorMessages: {
type: 'should be a string',
minLength: 'should be atleast of 23 length',
required: 'should have Authorization'
}
}
},
required: ['Authorization']
},
path: {
type: 'object',
additionalProperties: false,
properties: {
orgId: {
type: 'string',
minLength: 23,
maxLength: 36,
description: 'OrgId Id of the Organization.',
errorMessages: {
type: 'should be a string',
minLength: 'should be atleast of 23 length', // ---> B
maxLength: 'should not be more than 36 length',
required: 'should have OrgId'
}
}
},
required: ['orgId']
}
}
};
Now, in my express code, I created a request object so that I can test the validity of the JSON in this format.
router.get("/org/:orgId/abc", function(req, res){
var request = { //---> A
path: {
orgId : req.params.orgId
},
headers: {
Authorization : req.headers.Authorization
}
}
const Ajv = require('ajv');
const ajv = new Ajv({
allErrors: true,
});
let result = ajv.validate(schema, request);
console.log(ajv.errorsText());
});
And I validate the above request object (at A) against my schema using AjV.
The output what I get looks something like this:
data/headers should have required property 'Authorization', data/params/orgId should NOT be shorter than 23 characters
Now I have a list of concerns:
why the message is showing data word in the data/headers and data/params/orgId even when my variable name is request(at A)
Also why not my errormessages are used, like in case of orgId I mentioned: should be atleast of 23 length (at B) as a message, even then the message came should NOT be shorter than 23 characters.
How can I show request/headers instead of data/headers.
Also, the way I used to validate my path params, query params, header params, body param, is this the correct way, if it is not, then what can be the better way of doing the same?
Please shed some light.
Thanks in advance.
Use ajv-keywords
import Ajv from 'ajv';
import AjvKeywords from 'ajv-keywords';
// ajv-errors needed for errorMessage
import AjvErrors from 'ajv-errors';
const ajv = new Ajv.default({ allErrors: true });
AjvKeywords(ajv, "regexp");
AjvErrors(ajv);
// modification of regex by requiring Z https://www.regextester.com/97766
const ISO8601UTCRegex = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?Z$/;
const typeISO8601UTC = {
"type": "string",
"regexp": ISO8601UTCRegex.toString(),
"errorMessage": "must be string of format 1970-01-01T00:00:00Z. Got ${0}",
};
const schema = {
type: "object",
properties: {
foo: { type: "number", minimum: 0 },
timestamp: typeISO8601UTC,
},
required: ["foo", "timestamp"],
additionalProperties: false,
};
const validate = ajv.compile(schema);
const data = { foo: 1, timestamp: "2020-01-11T20:28:00" }
if (validate(data)) {
console.log(JSON.stringify(data, null, 2));
} else {
console.log(JSON.stringify(validate.errors, null, 2));
}
https://github.com/rofrol/ajv-regexp-errormessage-example
AJV cannot know the name of the variable you passed to the validate function.
However you should be able to work out from the errors array which paths have failed (and why) and construct your messages from there.
See https://ajv.js.org/#validation-errors
To use custom error messages in your schema, you need an AJV plugin: ajv-errors.
See https://github.com/epoberezkin/ajv-errors

sails waterline sort on number not working(sails-redis)

I am trying to do sort id
Modal:
module.exports = {
autoPK: false,
attributes: {
id: {
type: 'integer',
autoIncrement:true,
primaryKey: true
},
}
}
Query:
mymodal.find().sort({id: 'asc'}).exec(function (err, res) {
console.log(res)
});
Data:
[ { id: '2', },{ id: '1'},{ id: '11' } ]
Actual:
[ { id: '1', },{ id: '11'},{ id: '2' } ]
**Expected:
[ { id: '1', },{ id: '2'},{ id: '11' } ]**
Can anybody help me out. Please..
Sorting on string working, but on number(interger).
Is there any with my query or issue with sails waterline criteria sort
First you should do query find and later sort()
Modal.find()
.sort({id: 'asc'})
.exec(function(err, res) {
console.log(res)
});
I went through the sails-redis adapter index and schema, few things are missing. while parsing the input data like '11' the method not worried about the data type.
Data like { id: 1 } and { id: '1'} is consider to be different even though in the model
type: 'integer
specified.
sails-redis/lib/database/schema.js
changes code:
Schema.prototype.parse
.
.
case 'integer':
values[key] = parseInt(values[key]);
break;
case 'float':
values[key] = parseFloat(values[key]);
break;
}
}
.
.
changes working for me. Make sure the values[key] is not null
The documentation isn't great on this, but it looks like you might need to use binary notation if you pass an object to sort(). Easier to just pass a string:
Model.find().sort('id asc').exec(function (err, res) {
console.log(res)
});

Resources