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

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.

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".

Trying to access dot notation variable with a string

I'm working on creating a web form that can dynamically read a swagger endpoint to create form fields. Specifically right now I am trying to read the schemas from the component section defined by openAPI 3.
Example json:
{
"openapi": "3.0.1",
"info": {
.......
},
"paths": {
........
},
"components": {
"schemas": {
"FakeAppConfiguration": {
"type": "object",
"properties": {
"setting1": {
"type": "string",
"nullable": true
},
"setting2": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"OtherFakeAppConfiguration": {
........
},
"ThirdFakeAppConfiguration": {
........
}
}
}
}
}
Using this snippet of json as an example, I can easily get the names of the schemas that are defined by using (json has already been loaded into data using fetch)
for (let schema in data.components.schemas)
{
//this will print out FakeAppConfiguration, OtherFakeAppConfiguration, ThirdFakeAppConfiguration
console.log(schema);
}
My problem now comes in trying to access each of these schema trees without calling them directly. I could easily do data.components.schemas.FakeAppConfiguration, but that would defeat the purpose of making this dynamic. I've been trying to somehow use the strings obtained in the above loop to access what I want to no avail. Some examples of things I've tried are below. Anyone able to help me get further access without calling the variable directly with dot notation? I have also considered doing manual parsing of the JSON, but trying to avoid that. This is a react app, so if anyone can think of a library that could help, I'm all ears there as well.
//treating like a key
data.components.schemas['FakeAppConfiguration']
//trying to create a map
interface SchemaDef {
type: string,
properties: Properties,
//....etc,etc
}
let i = 0;
let schemas: Map<string, SchemaDef> = new Map<string, SchemaDef>();
for (let schema in data.components.schemas)
{
schemas.set(schema, data.components.schemas[i]);
i++;
}
You could iterate over the Object.entries() of your "schemas" object.
let schemas = {
"FakeAppConfiguration": {
"type": "object",
"properties": {
"setting1": {
"type": "string",
"nullable": true
},
"setting2": {
"type": "string",
"nullable": true
}
},
},
"FakeAppConfiguration2": {
"type": "object",
"properties": {
"setting1": {
"type": "string",
"nullable": true
},
"setting2": {
"type": "string",
"nullable": true
}
},
}
};
for (let [key, value] of Object.entries(schemas)) {
console.log(key, "\n\n", value);
}

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.

Modify Response Object in strapi

I would like to get a modified response object. For example I dont know how to get the user object without the roles.
The default response is:
{
"id": 6,
"username": "username",
"email": "user#email.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"role": {
"id": 2,
"name": "Authenticated",
"description": "Default role given to authenticated user.",
"type": "authenticated"
}
}
Now I want to get the same response without the role attribute.
{
"id": 6,
"username": "username",
"email": "user#email.com",
"provider": "local",
"confirmed": true,
"blocked": false
}
Currently you cannot do this in the Rest API unless you change the UserController provided by permissions plugin, which is not recommended.
What you can do then is to use the GraphQL plugin provided by Strapi, so you can query only the fields you need on client side.
The docs about how to use GraphQL plugin are here.
For anyone still struggling with this problem:
The latest versions of strapi do support custom queries, you can pass an array containing all the names of relations you wish to populate (only relations!).
If you don't want to populate any relationships, you can keep it empty, your controller would then look something like this:
module.exports = {
UserWithoutRoles: ctx => {
return strapi.query('user').findOne({ id: ctx.params.id }, ['']);
}
}
If you do wish to populate it, it would be like this:
module.exports = {
UserWithoutRoles: ctx => {
return strapi.query('user').findOne({ id: ctx.params.id }, ['role']);
}
}
Also see:
[https://strapi.io/documentation/3.0.0-beta.x/concepts/queries.html#api-reference][1]

Defining relation between models in loopback application

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

Categories

Resources