
Research
Security News
Malicious PyPI Package Exploits Deezer API for Coordinated Music Piracy
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
ra-data-simple-prisma
Advanced tools
Simple react-admin dataprovider for prisma, supporting audit logs and roles
Create a fullstack react-admin app adding just one file on the server!
Most of the examples will use Next.js but you can use any node-based server-side framework.
npm i ra-data-simple-prisma
yarn add ra-data-simple-prisma
pnpm i ra-data-simple-prisma
import { Admin, Resource } from "react-admin";
import { dataProvider } from "ra-data-simple-prisma";
const ReactAdmin = () => {
return (
<Admin dataProvider={dataProvider("/api", options)}>
<Resource name="users" />
</Admin>
);
};
export default ReactAdmin;
Simplest implementation ever:
// -- Example for Next Pages router --
// /api/[resource].ts <= catch all resource requests
import { defaultHandler } from "ra-data-simple-prisma";
import { prismaClient } from "../prisma/client"; // <= Your prisma client instance
export default async function handler(req, res) {
const result = await defaultHandler(req.body, prismaClient);
res.json(result);
}
// -- Example for Next App router --
// /app/api/[resource]/route.ts <= catch all resource requests
import { defaultHandler } from "ra-data-simple-prisma";
import { prismaClient } from "../prisma/client"; // <= Your prisma client instance
import { NextResponse } from "next/server";
const handler = async (req: Request) => {
const body = await req.json();
const result = await defaultHandler(body, prismaClient);
return NextResponse.json(result);
};
export { handler as GET, handler as POST };
To be used with an underscore after the source
name
Example
<List
{...props}
filters={[
<SelectInput
label="Status"
source={"status_enum"}
/>,
<DateInput
label="Created After or on"
source={"created_at_gte"}
/>,
<TextInput
label="Full-text Body search"
source={"body_search"}
/>,
<TextInput
label="User's language"
source={"user.settings.language_enum"} // <= drill down in relationships
/>,
<TextInput
label="Metadata's subkey"
source={"metadata_pgjson.key.subkey"}
/>,
]}
>
export default function handler(req) {
const session = await getServerSession(...);
await defaultHandler(req.body, prismaClient, {
audit: {
model: prismaClient.audit_log,
authProvider: authProvider(session)
},
});
...
}
audit:
audit log
table eg. prisma.auditLog
{id: "_id", date: "created_at"}
{create: true, update: true, delete: false}
All dataProvider methods can be overridden for a given resource, or all.
// /api/post.ts <= override default handler for specific resource
export default function handler(req) {
switch (req.body.method) {
case "create":
await createHandler<Prisma.PostCreateArgs>(req, prismaClient.post, {
connect: {
tags: "id",
// or
tagIds: {
tag: "id",
},
// or
mediaIds: {
postToMediaRels: {
media: "id",
}
},
},
audit: ...
debug: ...
});
return NextResponse.json(...);
case "delete":
await deleteHandler<Prisma.PostDeleteArgs>(req, prismaClient.post, {
softDeleteField: "deletedAt",
audit: ...
debug: ...
});
break;
case "deleteMany":
await deleteManyHandler<Prisma.PostDeleteManyArgs>(req, prismaClient.post, {
softDeleteField: "deletedAt",
audit: ...
debug: ...
});
break;
case "getList":
await getListHandler<Prisma.PostFindManyArgs>(
req,
prismaClient.post,
{
select: ...
where: ...
noNullsOnSort: ...
filterMode: ...
debug: ...
include: { tags: true },
transformRow: (post: ServerPost, postIndex: number, posts: ServerPost[]): AugmentedPost => {
return {
...post
tagIds: post.tags.map((tag) => tag.id);
}
},
}
);
// OR, if using InfiniteList compoenent
await getInfiniteListHandler<Prisma.PostFindManyArgs>(
req,
prismaClient.post,
{
select: ...
where: ...
noNullsOnSort: ...
filterMode: ...
debug: ...
include: { tags: true },
transformRow: (post: ServerPost, postIndex: number, posts: ServerPost[]): AugmentedPost => {
return {
...post
tagIds: post.tags.map((tag) => tag.id);
}
},
}
);
break;
case "getMany":
await getManyHandler<Prisma.PostFindManyArgs>(
req,
prismaClient.post,
);
break;
case "getManyReference":
await getManyReferenceHandler<Prisma.PostFindManyArgs>(
req,
prismaClient.post,
);
break;
case "getOne":
await getOneHandler<Prisma.PostFindUniqueArgs>(
req,
prismaClient.post,
{
select: ...
include: ...
transform: (post: any) => {
post._computedProp = ...
},
transform: async (
post: QueryPost
): Promise<QueryPost & { _extraPropAfterTransform: true }> => {
return {
...post,
_extraPropAfterTransform: await Promise.resolve(true),
};
},
}
)
break;
case "update":
await updateHandler<Prisma.PostUpdateArgs>(
req,
prismaClient.post,
{
skipFields: {
computedField: true
},
set: {
tags: "id",
},
allowNestedUpdate: {
user_settings: true,
fixed_settings: false,
},
allowNestedUpsert: {
other_settings: true
},
allowJsonUpdate: {
raw_data_field: true;
}
}
);
break;
case "updateMany":
await updateManyHandler<Prisma.PostUpdateManyArgs>(
req,
prismaClient.post,
{
skipFields: {
computedField: true
},
set: {
tags: "id",
},
}
);
break;
default: // <= fall back on default handler
await defaultHandler(req, prismaClient, {
audit: ...
create: ...
delete: ...
getList: ...
getMany: ...
getManyReference: ...
getOne: ...
update: ...
});
break;
}
}
Stuff you can use to write your own custom logic
In your Api handler, call the function canAccess
to infer if the user (session) can perform that particular action.
Example in admin demo
It will need the permission object which looks like this
export const permissionsConfig: PermissionsConfig = {
OWNER: [{ action: "*", resource: "*" }], //admin can do anything
COLLABORATOR: [
//collaborator can do anything except edit, delete, create admin users
{ action: "*", resource: "*" },
{
type: "deny",
action: ["edit", "delete", "create"],
resource: "adminUser",
},
],
READER: [{ action: ["list", "show", "export"], resource: "*" }],
};
Use the example app to test the changes.
In root folder run
pnpm publish
MIT
FAQs
Simple react-admin dataprovider for prisma, supporting audit logs and roles
The npm package ra-data-simple-prisma receives a total of 1,580 weekly downloads. As such, ra-data-simple-prisma popularity was classified as popular.
We found that ra-data-simple-prisma demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.
Security News
Newly introduced telemetry in devenv 1.4 sparked a backlash over privacy concerns, leading to the removal of its AI-powered feature after strong community pushback.