{"id":13510374,"url":"https://github.com/dai-shi/social-cms-backend","last_synced_at":"2025-10-03T02:30:22.842Z","repository":{"id":57364969,"uuid":"10996087","full_name":"dai-shi/social-cms-backend","owner":"dai-shi","description":"Express middleware to provide schema-less REST APIs for creating a social networking website primarily using angular.js. It comes with built-in authentication, authorization and notification features.","archived":false,"fork":false,"pushed_at":"2018-10-13T01:01:55.000Z","size":14849,"stargazers_count":215,"open_issues_count":2,"forks_count":34,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-01-15T01:21:31.474Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://dai-shi.github.io/social-cms-backend/","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/dai-shi.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}},"created_at":"2013-06-27T12:18:29.000Z","updated_at":"2025-01-04T02:40:27.000Z","dependencies_parsed_at":"2022-09-13T21:11:57.256Z","dependency_job_id":null,"html_url":"https://github.com/dai-shi/social-cms-backend","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dai-shi%2Fsocial-cms-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dai-shi%2Fsocial-cms-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dai-shi%2Fsocial-cms-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dai-shi%2Fsocial-cms-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dai-shi","download_url":"https://codeload.github.com/dai-shi/social-cms-backend/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235059581,"owners_count":18929289,"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-08-01T02:01:36.444Z","updated_at":"2025-10-03T02:30:17.470Z","avatar_url":"https://github.com/dai-shi.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"readme":"social-cms-backend\n==================\n\n[![Build Status](https://travis-ci.org/dai-shi/social-cms-backend.svg?branch=master)](https://travis-ci.org/dai-shi/social-cms-backend)\n[![npm version](https://badge.fury.io/js/social-cms-backend.svg)](https://badge.fury.io/js/social-cms-backend)\n\nExpress middleware to provide schema-less REST APIs for creating a social networking website primarily using angular.js. It comes with built-in authentication, authorization and notification features.\n\nMotivation\n----------\n\nThere exists several MVC framework libraries for node.js\nthat are inspired by Rails.  But they might be a bit outdated,\nwhen it comes to angular.js, client-side MVW framework.\nI would like to propose a maybe new style of web programming,\nwhich is the combination of a domain-specific REST API library\n(ready to use, no coding required) and client-side coding.\n\nThis project is to provide such a library for a web site\nlike SNS/Twitter/Facebook in a closed/private environment.\n\nHow to install\n--------------\n\n    $ npm install social-cms-backend\n\nExamples\n--------\n\nThe followings are minimal example code that uses social-cms-backend.\n\n- [auth-local](examples/auth-local/) --- Simple BBS with local authentication\n- [digest-and-following](examples/digest-and-following/) --- An example app using digest auth and following feature (w/ socket.io)\n\nScreencast\n----------\n\n### How to create a Twitter clone in 15 minutes\n\nScreencast preview (quadruple speed):\n\n![Preview](http://dai-shi.github.io/social-cms-backend/ttyrecord.gif)\n\n\u003ca href=\"http://dai-shi.github.io/social-cms-backend/ttyplay.html\" target=\"_blank\"\u003eControllable screencast at normal speed\u003c/a\u003e\n\nNotes:\n\n* There is a typo found after the recording.\n  `/javascript/main.js -\u003e /javascripts/main.js`\n* The resulting code is available\n  [here](https://github.com/dai-shi/twitter-clone-sample/tree/20130804_recorded)\n\nHow to use\n----------\n\n### Minimal configuration with local authentication\n\n    var express = require('express');\n    var SCB = require('social-cms-backend');\n    var app = express();\n    app.use(SCB.middleware({\n      mongodb_url: 'mongodb://localhost:27017/socialcmsdb',\n      passport_strategy: 'local'\n    }));\n    app.listen(3000);\n\n### Typical configuration with Facebook authentication:\n\n    var express = require('express');\n    var SCB = require('social-cms-backend');\n    var app = express();\n    app.use(SCB.middleware({\n      mongodb_url: 'mongodb://localhost:27017/socialcmsdb',\n      passport_strategy: 'facebook',\n      facebook_app_id: process.env.FACEBOOK_APP_ID,\n      facebook_app_secret: process.env.FACEBOOK_APP_SECRET\n    }));\n    app.listen(3000);\n\nNotice two environment variables which have to be obtrained from \u003chttps://developers.facebook.com/\u003e and set properly. Refer [Facebook Doc](https://developers.facebook.com/docs/apps/register) for more information.\n\n### Configuration with socket.io v1.0:\n\n    var http = require('http');\n    var express = require('express');\n    var socket_io = require('socket.io');\n    var expressSession = require('express-session');\n    var SCB = require('social-cms-backend');\n    var app = express();\n    var SCB_options = {\n      mongodb_url: 'mongodb://localhost:27017/socialcmsdb',\n      session_middleware: expressSession({\n        secret: process.env.SESSION_SECRET,\n        resave: false,\n        saveUninitialized: true\n      }),\n      passport_strategy: 'facebook',\n      facebook_app_id: process.env.FACEBOOK_APP_ID,\n      facebook_app_secret: process.env.FACEBOOK_APP_SECRET\n    };\n    app.use(SCB.middleware(SCB_options));\n    var server = http.createServer(app);\n    var sio = socket_io(server);\n    sio.use(SCB.socket_io(SCB_options));\n    server.listen(3000);\n\n### Configuration for HTTP DIGEST strategy:\n\n    var SCB_options = {\n      mongodb_url: 'mongodb://localhost:27017/socialcmsdb',\n      passport_strategy: 'digest',\n      auth_digest: {\n        realm: 'my_realm'\n      }\n    };\n\n### Configuration with BreezeJS support:\n\n    var SCB_options = {\n      mongodb_url: 'mongodb://localhost:27017/socialcmsdb',\n      breeze_mongo: true,\n      routes: [{\n        object_type: 'user',\n        object_prefix: '/breeze-service/users'\n      }, {\n        object_type: 'post',\n        object_prefix: '/breeze-service/posts'\n      }, {\n        object_prefix: '/breeze-service/SaveChanges'\n      }]\n    };\n\n\nLogin APIs\n----------\n\nThe login API for Facebook authenticate is the following:\n\n    GET /login/facebook\n\nTypically, the HTML would look like this:\n\n    \u003ca href=\"/login/facebook\"\u003eLogin\u003c/a\u003e\n\nIn the case of DIGEST authentication, the API is:\n\n    GET /login/digest\n\nThe way to create a user for DIGEST authentication is:\n\n    POST /adduser/digest\n    Content-Type: application/json\n    Content-Length: ...\n    \n    {\"name\":\"...\",\"passhash\":\"...\",\"initdata\":\"{...}\"}\n\n\nREST APIs\n---------\n\nBy default, there are 4 object types:\n* user\n* group\n* post\n* like\n\nThe following is the example of the post object endpoint.\n\n### List post objects\n\n    GET /posts?query=...\n\nThe \"query\" query parameter is a MongoDB query parameter object\nthat is stringified (probably by JSON.stringify).\n* `skip` and `limit` query parameters are also supported.\n\n### Get one post object\n\n    GET /posts/123\n\nThe \"123\" is the `_id` of the post.\n\n### Save a new post\n\n    POST /posts\n\nThe body is an object (JSON format) without system preserved properties such as\n`_id`, `system`, `created_time`, `owner`, `meta`.\n\n### Update a post\n\n    PUT /posts/123\n\nThe body is a MongoDB update object (JSON format) using update operators.\n\n### Delete a post\n\n    DELETE /posts/123\n\n### Count posts\n\n    GET /posts/count?query=...\n\nThis is a special endpoint.\n\n### Get following posts\n\n    GET /posts/inbox\n\nThis is a special endpoint to only get posts that matches with predefined \"following\".\nMore description follows in the next section.\n\n### Aggregate Posts\n\n    GET /posts/aggregate?pipeline=...\n\nThis is a special endpoint to use MongoDB aggregate command.\nThe \"pipeline\" query parameter is a MongoDB pipeline parameter object\nthat is stringified (probably by JSON.stringify).\n\nUser and Group\n--------------\n\nUser objects can also be accessed by REST API.\nFor example, all user list can be fetched by\n\n    GET /users\n\nunless othrewise restricted.\n\nTo get login user information, use this special endpoint.\n\n    GET /users/myself\n\nTo create a group, save a group object like the following:\n\n    {\n      members: [\n        { user_id: 111 },\n        { user_id: 112 },\n        { user_id: 113 }\n      ]\n    }\n\nThe `user_id` is the `_id` attribute of a user object.\n\nYou can also define nested groups like the following:\n\n    {\n      members: [\n        { user_id: 111 },\n        { group_id: 211 },\n        { group_id: 212 }\n      ]\n    }\n\nThe `group_id` is the `_id` attribute of a group object.\n\nAccess Control\n--------------\n\nObject read permission is handled by the `scope` attribute.\nFor example, if an object has the `scope` like this,\n\n    {\n      data: { ... },\n      scope: [\n        { user_id: 111 },\n        { group_id: 211 }\n      ]\n    }\n\nthis object can only be accessed by the user `user_id=111` and\nall members of the group `group_id=211`.\nNotice `data` attribute is just an example.\n\nObject write permission is based on ownership,\nwhich means an object can only be updated by the user who first saved.\n\nThese access control can be customized by `hasPermission` SCB option.\n\nFollowings and Followers\n------------------------\n\nThere is a special endpoint `inbox`.\nif an object has `destination` property and if a user follows\nthat destination, that object is added to the user `inbox`.\nFor example, suppose a user with `user_id=111` follows\nanother user with `user_id=112`, a user object will be\n\n    {\n      _id: 111,\n      following: [{\n        user_id: 112\n      }]\n    }\n\nand if an object has `destination` like the following\n\n    {\n      destination: [{\n        user_id: 112\n      }]\n    }\n\nthe user with `user_id=111` will see this object in one's own `inbox`.\n\nA user can also follow a group, in this case the user object would look\nlike the following.\n\n    {\n      _id: 111,\n      following: [{\n        group_id: 211\n      }]\n    }\n\nThere is an SCB option `always_follow_myself` and if it is `true`,\nit is equivalent to having a user `user_id=111` object like\n\n    {\n      _id: 111,\n      following: [{\n        user_id: 111\n      }]\n    }\n\nfor all users.\n\nPush by socket.io\n-----------------------------\n\nIf an object has a `destination` property and a user follows it,\nthe server pushes the object to to the user by socket.io,\nif socket.io is configured properly (See the example in \"How To Use\").\n\nFor example, if a \"post\" object like the following is inserted;\n\n    {\n      destination: [{\n        group_id: 211\n      }]\n    }\n\nall the users who follow `group_id=211` will receive the whole object\nas a message identified by `new-post`.\nSo the clients of the users are expected to listen to it by the following.\n\n    socket.on('new-post', function(data) {\n      //do something with data\n    });\n\nExtension to JSON format\n------------------------\n\nSometimes, we want to encode JavaScript objects in JSON.\nWe have a special notion for `Date` and `RegExp` like the following.\n\n    {\"key1\":\"val1\",\"key2\":\"/Date(12345)/\"} //12345 is milliseconds\n\n    {\"key3\":\"val3\",\"key4\":\"/RegExp([A-Z][a-z]+)/\"}\n\nDefining Object Types\n---------------------\n\nThe examples above are all about the post object.\nYou can define any objects and their routes in an SCB option.\n\n    routes: [{\n      object_type: 'user',\n      object_prefix: '/rest/users'\n    }, {\n      object_type: 'group',\n      object_prefix: '/rest/groups'\n    }, {\n      object_type: 'article',\n      object_prefix: '/rest/articles'\n    }, {\n      object_type: 'comment',\n      object_prefix: '/rest/comments'\n    }, {\n      object_type: 'like',\n      object_prefix: '/rest/likes'\n    }]\n\nHowever, keeping `user` and `group` objects are always required for\nauthentication and authorization.\n\nIf you want to create a unique index, you can define it in an SCB option.\n\n    ensure_unique_index: {\n      object_type: 'like',\n      object_fields: ['owner', 'article_id']\n    }\n\nThis will restrict one \"like\" at most for one article for each user.\n\nTODOs\n-----\n\n* Notification: email\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdai-shi%2Fsocial-cms-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdai-shi%2Fsocial-cms-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdai-shi%2Fsocial-cms-backend/lists"}