Defining relation between models in loopback application - javascript

I am working on an app using loopback .
Need help and suggestions on models relationship and role.
Multiple organisations
An organisation have multiple admin and multiple user.
I'm using relation like
Organisation hasMany. User
User belongs to organisation
Created a admin role.Don't want use $owner because in future may owner is not available.
created two models users and organization
How can I list all user belongs to a organisation.
How to differentiate b/w Admins/Users of different org.
Do I have to create custom filter for that?
//user.json
"properties": {
"email": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"organization": {
"type": "belongsTo",
"model": "Organization",
"foreignKey": "orgUserId"
},
"templates": {
"type": "hasMany",
"model": "Template",
"through": "Share"
}
}
}
//organization.json
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"relations": {
"users": {
"type": "hasMany",
"model": "user",
"foreignKey": "orgUserId",
"properties" :{
"name": "realm"
}
},
"templates": {
"type": "hasMany",
"model": "Template",
"through": "Share"
}
},
Please help.
Thanks

How can I list all user belongs to a organization ?
Since you've defined User belongsTo and Organization hasMany relationship you could simply make the following request :
GET api\Organization\{ID}\users
How to differentiate b/w Admins/Users of different org.`
First you should setup admin and team member (for instance) roles, then check in a role resolver script (example) that any user with admin role for a given organizationID is well indeed trying to make admin operation for that organization and not an other.
This is well documented in there
https://docs.strongloop.com/display/public/LB/Defining+and+using+roles
You should also check and study all this github repository, it has most of the information you're looking for:
https://github.com/strongloop/loopback-example-access-control

Related

Need to do schema Validation with multiple references using jsonschema npm package in react

I need to do the complex schema validation, which has multiple $ref in it. I am using jsonschema npm package to achieve it.
Example:
Parent Schema : - parent.json id: https://example.com/ww/ee/parent.json $ref:
sample.json#/definitions/event
Child Schema: - child.json id: https://example.com/ww/ee/child.json Child has event properties in
it.
I have placed these 2 json files in local folder called schemas. Now the issue is, i am trying to add reference child schema. But i am getting following error,
stack: "SchemaError: no such schema https://example.com/ww/ee/child.json#/definitions/event\n
at Validator.resolve (http://localhost:3000/static/js/bundle.js:18810:11)\n
at Validator.validateSchema (http://localhost:3000/static/js/bundle.js:18724:25)\n
at Validator.validateProperties (http://localhost:3000/static/js/bundle.js:17209:20)\n
at Validator.validateSchema (http://localhost:3000/static/js/bundle.js:18737:34)\n
at Validator.validateSchema (http://localhost:3000/static/js/bundle.js:18726:17)\n
at Validator.validate (http://localhost:3000/static/js/bundle.js:18654:21)\n
at module.exports.validate (http://localhost:3000/static/js/bundle.js:18393:12)\n
at filterNotification (http://localhost:3000/static/js/bundle.js:1143:25)\n
at async Function.startSendData (http://localhost:3000/static/js/bundle.js:1026:30)"
[[Prototype]]: Error
const schema = require('../schemas/parentschema.json')
const eventSchema = require('../schemas/childSchema.json')
const validator = new Validator();
validator.addSchema(eventSchema, 'https://example.com/ww/ee/childSchema.json')
const isValidSchema = validator.validate(JsonObjectTovalidate, schema)
Parent schema:
"$ref": "#/definitions/noify",
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "https://example.com/ww/ee/parentschema.json",
"description": "Sample",
"definitions": {
"noify": {
"description": "sample",
"properties": {
"events": {
"description": "sample",
"items": {
"$ref": "childSchema.json#/definitions/event"
},
"type": "array",
"maxItems": 250
},
},
"title": "testing",
"type": "object",
"additionalProperties": false
}
},
}
Child Schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"version": "1.4.0",
"description": "Promoting",
"id": "https://example.com/ww/ee/childSchema.json",
"$ref": "#/definitions/event",
"definitions": {
"event": {
"properties": {
"dateTime": {
"$ref": "otherSchema.json#/definitions/dateTime",
"description": "Originator datetime when the event actually occured"
},
"additionalProperties": false
},
},
}
In the child schema, if I remove this line, "$ref": "#/definitions/event", then it is working fine. Why is that so? without removing how can i make it to work?
In draft4 of JSON Schema, $ref cannot exist side-by-side with any other keyword. However, it doesn't look like you require that $ref to be there in your childSchema.json document - you reference this document as "childSchema.json#/definitions/event", not simply "childSchema.json", so it should be fine to remove.
Alternatively you can move the definition in childSchema.json to the top level (remove the "definitions" and "event" keywords entirely, moving the schema up two levels to the base of the document) and remove the $ref in that file, and refer to it as "$ref": "childSchema.json".

Requesting info out of DISCORD API INVITES

I would like to know how can i request this two values from the https://discord.com/api/v8/invites/, getting the first channel's name and the name of the guild.
Cause im looking foward to do so every invite sent in a channel must have a specific word in the guild name it is from and a specific word as first channel, otherwise it will get deleted.
I would appreciate some help since im new to this a docs got me really confused. Thanks!
If you try using the API, (this example uses unblock)
You get this response:
{
"code": "unblock",
"guild": {
"id": "419123358698045453",
"name": "TitaniumNetwork",
"splash": "86378b9059a3fe6d7a76d126c3c4b678",
"banner": "86378b9059a3fe6d7a76d126c3c4b678",
"description": null,
"icon": "870e49b4cd8fce8063b7bda48e33aa46",
"features": ["COMMUNITY", "WELCOME_SCREEN_ENABLED", "VANITY_URL", "ANIMATED_ICON", "BANNER", "PREVIEW_ENABLED", "INVITE_SPLASH", "MEMBER_VERIFICATION_GATE_ENABLED", "NEWS"],
"verification_level": 4,
"vanity_url_code": "unblock",
"welcome_screen": {
"description": "We are an organization revolving around proxies, armed with a mission for the protection of freedom and privacy rights to be normalized.",
"welcome_channels": [{
"channel_id": "738967801460686889",
"description": "Read the rules.",
"emoji_id": "709447784536866869",
"emoji_name": "verif"
}, {
"channel_id": "796606512407511060",
"description": "Join some discussions!",
"emoji_id": "766746158546026547",
"emoji_name": "infernal"
}, {
"channel_id": "743646448721068092",
"description": "Talk about tech!",
"emoji_id": "779561163293196288",
"emoji_name": "abraded"
}, {
"channel_id": "769716455230668820",
"description": "Be ready for feedback!",
"emoji_id": "574816517989072897",
"emoji_name": "TitaniumNetwork"
}]
}
},
"channel": {
"id": "738967801460686889",
"name": "rules",
"type": 0
}
}
It's a simple matter of parsing the JSON.

How to get current user's data from loopback API?

I'm using loopback to create an API. So far I've been able to set up all the models that I require. How can we set up these endpoints so that they show the data for only the user that has been logged in?
For example, user A adds some data in the database and user B adds some other data in the database. Now if user A is logged in, I only want to get the data that was added by A. As of now I'm getting all the data present in the database together.
My model JSON is as follows:
{
"name": "IPs",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"identifier": {
"type": "string"
},
"IP": {
"type": "array"
},
"type": {
"type": "string"
},
"plugins": {
"type": "array"
}
},
"validations": [],
"relations": {},
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$unauthenticated",
"permission": "DENY"
}
],
"methods": {}
}
and JS is as follows:
module.exports = function(IPs) {
};
Change principalId of the model from $unauthenticated to $owner
Note from loopback documentation:
To qualify a $owner, the target model needs to have a belongsTo relation to the User model (or a model that extends User) and property matching the foreign key of the target model instance. The check for $owner is performed only for a remote method that has ‘:id’ on the path, for example, GET /api/users/:id.

Is it appropriate to use Apollo local state to store a different representation of returned data

I have an Apollo Client that I'm using to request data from a service. I want to use the data I get in response to create a network of nodes and links e.g.
// Response data:
{
"Team": [
{
"name": "Example Team",
"members": [
{ "name": "Bob" },
{ "name": "Alice" }
]
}
]
}
// Network data:
{
"nodes": [
{ "name": "Example Team" }
{ "name": "Bob" },
{ "name": "Alice" }
],
"links": [
{ "source": "Example Team", "target": "Bob" },
{ "source": "Example Team", "target": "Alice" }
]
}
Historically, before using GraphQL, I would have used Redux to store the munged API response in state and read from there.
Is it appropriate to take a GraphQL result from Apollo and immediately save it back to Apollo local state in a different form so it can be queried by components in that format?
The main problem I foresee is that I think I'd have to query to check if the data I want exists in local state, then make another query if it didn't. In a Redux-world this would be wrapped up inside my store which would then only make the request off to the API if it didn't have the data it needed which 'feels' much cleaner.
In my case this could be solved using Afterware in Apollo Client, see this answer for more information.
It would allow me to munge the returned data into the form I need, and return it in the response alongside the original data.

Parsing input based on JSON schema

We're building a frontend project for a web app that communicates with a backend written by another team. Some of the developers work on both projects, and have better understanding of changes to the backend and response fields coming back.
Recently we had portions of frontend break as they made changes in parts of the app based on changes to the backend without updating the logic in all places. To mitigate this I want to put in place a concept of a mask/template that all response data would be curated through. That way the rest of the members on the team who're not as familiar with the backend can notice/address these bugs.
To do so, I'm considering using JSON Schema. Instead of simply validating, however, I want to parse the backend data through it (removing the fields not present in the schema). This way the developer making changes in the frontend in response to a backend change would also need to update this template, therefore triggering a test failure until all logic using this schema is updated (not just the logic he touched). I'm playing with https://www.npmjs.com/package/jsonschema, but it doesn't seem to have a way to remove excess fields, just test for them.
Within JSON Schema, I can also set additionalProperties flag. However, it has 2 problems with it:
It doesn't cause the validator to remove the fields, it simply dumps them to error array
It needs to be set individually at each nested level, therefore I need to traverse the entire JSON structure, at which point I basically end up writing my own parser/validator.
Perhaps validator is not the right tool for this, but that's all I'm finding when searching for JSON schema parsers. Can someone guide me in the right direction so that I don't reinvent the wheel? It sounds like this functionality is very similar to what a validator already does and I would rather do this processing in the same pass.
Found a validator that does what I want: https://github.com/acornejo/jjv. It has removalAdditional flag that I can set, here is a quick test I did:
var jjv = require('jjv')();
var addressSchema = {
"id": "address",
"type": "object",
"properties": {
"lines": {
"type": "array",
"items": {"type": "string"}
},
"zip": {"type": "string"},
"city": {"type": "string"},
"country": {"type": "string"}
},
"required": ["country"]
};
var schema = {
"id": "person",
"type": "object",
"properties": {
"name": {"type": "string"},
"address": {"$ref": "address"},
"votes": {"type": "integer", "minimum": 1}
}
};
var p = {
"name": "Barack Obama",
"address": {
"lines": [ "1600 Pennsylvania Avenue Northwest" ],
"zip": "DC 20500",
"city": "Washington",
"foobar": "baz",
"country": "USA"
},
"a": {
"b": 1,
"c": 2
},
"votes": "lots",
"stuff": "yes"
};
jjv.addSchema('address', addressSchema);
jjv.addSchema('schema', schema);
jjv.defaultOptions.checkRequired = true;
jjv.defaultOptions.removeAdditional = true;
console.log(jjv.validate('schema', p));
console.log(p);
And a response:
{ validation: { votes: { type: 'integer' } } }
{ name: 'Barack Obama',
address:
{ lines: [ '1600 Pennsylvania Avenue Northwest' ],
zip: 'DC 20500',
city: 'Washington',
country: 'USA' },
votes: 'lots' }

Categories

Resources