Another Closed Social Network approach. Based on Mojolicious
JavaScript CSS Perl Perl 6
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Closed Social Network

Closed Social Network (CSN) is designed to provide a safe and anonym environment for a community. Each user needs an invitation to join the network and after a specific time (which depends on the amount of active users) the new user can also invite other users.


CSN is released under the MIT License. For the full license text check the file LICENSE.

Embedded libraries with different licenses

  • bootstrap-markdown.js: Apache 2
  • cytoscape.js: LGPL 3
  • select2.js: Apache 2
  • selectize.js: Apache 2


  • Perl 5
  • PostgreSQL >= 9.1
  • Redis >= 2.8

Supported browsers

  • Tested with Chrome and Firefox (latest versions)
  • Only browsers which support HTML5 and Websockets


Required modules

After cloning the repository install all required perl modules listed in cpanfile.

You could do this manually or with cpanm


config.yml holds all configuration data like database and redis uri, necessary unique ids, etc. The most keys should be self-explanatory, the other keys will be explained below:


A unique id for each running CSN instance to avoid pub/sub collisions on shared redis instances or between production, development and testing.


A Mojolicious specific key which is used to secure session data. Keep it private.


An array of hashes which defines which languages are available. key is the 2 letter iso code which identifies the language and is used for the i18n files. flag is the iso alpha2 code to identify the asigned county flag and only necessary to display the flag in the language picker. If the user specifies no language, the HTTP header detection fails and the configured (csn.conf) default language is invalid, the first defined language will be used as default language.


An array which lists all chat rooms that should be available. Each chat room needs the following i18n keys:

  • chat_room_{ROOMKEY} as room title
  • chat_room_header_{ROOMKEY} as room header
  • chat_room_welcome_message_{ROOMKEY} as welcome message for the joining user


A config file which should return a perl hash. It holds the default values of the user settings, defines the available bootstrap themes, defines the FAQ language keys and can be used to provide parameters to hypotoad.


Initialize the database by executing initdb.sql with your CSN database user.

UTC timezone

CSN relies on the UTC timezone of PostgreSQL. Assure that your PostgreSQL uses UTC as timezone or assign your CSN-user the UTC timezone.

Initial user

To create the first user adjust and execute the following SQL snippet:

INSERT INTO Account (username, password, is_admin) VALUES('admin',  '{X-PBKDF2}HMACSHA1:AAAD6A:n2ahmA==:O7kgtqIpejMguKM8q7XBTr/z19M=', 't');

The default password is 'Default123'.


Profile fields

Profile fields are generated from database entries. The table ProfileField stores the field configuration and ProfileFieldOption the possible predefined values of each field.

CSN supports the following profile field types:

  • input
  • select
  • select_free
  • text
  • date
  • time (not yet finished)
  • select_multi
  • select_multi_free
  • checkbox

Where select, select_multi and checkbox need additional options in ProfileFieldOption and the corresponding i18n keys.

*_free fields accept any data from the user and suggest values which are allready saved by other users.

The fields need the following i18n keys:

  • profile_field_{LANGUAGE_KEY} as field title/description
  • profile_field_{LANGUAGE_KEY}_edit_title as title of the edit popup if it's a select field

Message board

Message boards and sections are also generated from database entries. The table Board defines the main boards with their order and language key and the table BoardSection the subsection of each board with their order and language key.

The boards and sections need the following i18n keys:

  • {LANGUAGE_KEY}_title as board/section title
  • {LANGUAGE_KEY}_description as a short description of the board/section


Internationalization is provided by Locale::Wolowitz. All i18n files need to be placed in the subdir i18n. Previous defined keys (like title, descriptions, etc.) can be overwritten if you place your own i18n file beside the default one and give it a name that ensures that it will be loaded after the default one (e.g. xxx.my_locales.coll.json). Additional languages can be added by providing a file with the new language entries, it will be merged with the existing languages.

If a key isn't translated for any language the key will be shown if this language is selected.


CSN has no e-mail support

CSN relies on vouchers and not on email verification. It also supports the anonymity of the user and the operator which results in a complete lack of email support.

The user forgetts the username or password: The account is lost.

CSN has no upload support

It's not planned to add some sort of upload (attachments, profile picutres, etc.) functionality because we won't trust the user, even if it's a simple txt file.

Tor support

CSN is designed to be operated as Tor Hidden Service.

All chat messages are volatile

The chat uses redis pub/sub functionality to deliver the messages. There is no chat history or something similar.

Bootstrap themes without Google fonts

All imports from are removed because we don't like to include external stuff for security reasons.


Support / Feature requests

Raise a ticket if it's CSN related. If you experience problems with a specific instance try to contact your operator.

Update DBIX files

To create or update the DBIX files use the following command from within the base directory:

DATABASE=csn_dev DBUSER=csn DBPASS=csn DBIC_OVERWRITE_HELPER_METHODS_OK=false; dbicdump -o dump_directory=./lib -o rel_name_map='{ Account => { accounts => "invitees", unreadmessages => "unreadmessages_mapping", unreadmessages_2s => "messages", messages => "unreadmessages", profilevisitor_accounts => "visitors", profilefollow_accounts => "followed", profilefollows_followed => "follower"}}' -o components='["InflateColumn::DateTime"]' CSN::Schema "dbi:Pg:dbname=${DATABASE};host=;port=5432" ${DBUSER} ${DBPASS}