{"id":15792837,"url":"https://github.com/nfour/urn-schema","last_synced_at":"2025-03-31T18:51:35.774Z","repository":{"id":149654870,"uuid":"64648407","full_name":"nfour/urn-schema","owner":"nfour","description":"URN Schema Validator","archived":false,"fork":false,"pushed_at":"2016-08-06T23:50:38.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-11T23:18:40.977Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nfour.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-01T08:08:48.000Z","updated_at":"2016-08-02T07:41:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"f45069e4-b32f-4511-9488-8761ea6d0cea","html_url":"https://github.com/nfour/urn-schema","commit_stats":{"total_commits":14,"total_committers":1,"mean_commits":14.0,"dds":0.0,"last_synced_commit":"a364ccd3c66c29f2b54aede52701f254edc16417"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfour%2Furn-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfour%2Furn-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfour%2Furn-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfour%2Furn-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nfour","download_url":"https://codeload.github.com/nfour/urn-schema/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246523897,"owners_count":20791444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-04T23:05:14.534Z","updated_at":"2025-03-31T18:51:35.741Z","avatar_url":"https://github.com/nfour.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# URN Schema\n\nThis library handles URN schemas, similar to AWS ARN's, useful for access control.\n\nFeatures:\n- [x] Variable interpolation `urn:${some.dataset}`\n- [x] Wildcarding `urn:*`\n- [x] Precompilation for performance\n- [x] Uri validation `urn:this/${is.a}/*/uri?with\u0026a\u0026query`\n- [x] ACL's\n- [x] Conforms to [URN](https://en.wikipedia.org/wiki/Uniform_Resource_Name)\n\n```js\nimport UrnSchema, { UriValidator } from 'urn-schema'\n\nconst schema = new UrnSchema('version:method:scope:uri', {\n    uri: UriValidator,\n})\n\nconst acl = schema.createAcl({\n    group_a: [\n        \"urn:1.0:POST:testing:products/*/items/*\"\n    ]\n})\n\nacl.validate('group_a', {\n    version : '1.0',\n    method  : 'POST',\n    scope   : 'testing',\n    uri     : 'products/22/items'\n}) // returns { valid: true, group: 'group_a' }\n\nacl.validate('group_a', {\n    version : '2.0',\n    method  : 'GET',\n    scope   : 'testing',\n    uri     : 'products/22/items'\n}) // returns { valid: false, group: 'group_a' }\n\n```\n\nIn the basic example above we have defined a schema which matches predefined properties, including parsing the `uri` appropriately.\n\nBelow is a more advanced example.\n\n```js\nconst acl = schema.createAcl({\n    group_a: [\n        \"urn:${versions}:GET:${scopes}:products/${user['!~validIds~!']}/*?direction\u0026order\"\n    ]\n})\n\nconst data = {\n    versions: [ '1.0', '2.0' ],\n    scopes: [ 'testing', 'staging' ],\n    user: {\n        \"!~validIds~!\": [ 22, 24, 77 ]\n    }\n}\n\nacl.validate('group_a', {\n    version : '2.0',\n    method  : 'GET',\n    scope   : 'testing',\n    uri     : 'products/22/items?order=size'\n}, data) // returns { valid: true, group: 'group_a' }\n```\n\nIn the above example the variables defined in `group_a`'s first urn are interpolated from the `data` object.\n\nThese uri's would also pass:\n- `products/24/`\n- `products/27/something?direction=asc`\n\nAnd so too would version `1.0` and scope `staging`.\n\nIt's easy to parse a full URL into something you can use against the schema.\nImagine the below `originalUrl` is `/2.0/testing/products/22`.\n\n```js\napp.use((req, res, next) =\u003e {\n    const { method, originalUrl, auth } = req\n\n    // Take off the first 2 parts\n    let [ version, scope, ...uri ] = originalUrl\n        .replace(/^\\/|\\/$/g, '') // Remove trailing \u0026 leading slashes\n        .split('/')\n\n    uri = uri.join('/') // Join it back up\n\n    const aclCheck = acl.validate(auth.scope, {\n        version, scope, method, uri\n    })\n\n    if ( aclCheck.valid )\n        return next()\n\n    return next( new ForbiddenError(\"Permission denied!!!\") )\n})\n\n```\n\n### Interpolation Mechanics\n\nWhen a variable is interpolated, the type matters.\n\n- If `${some.data}` resolves to an array `[1, 2]`, then the value can match either of them, as a string comparison\n- If `${some.data}` resolves to any other type, it will be stringified and compared against the value\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnfour%2Furn-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnfour%2Furn-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnfour%2Furn-schema/lists"}