Source: https://github.com/mbland/custom-links
An application for allowing authenticated users to create and dereference custom URLs hosted on a custom domain.
For example, if you run an instance of Custom Links that can be accessed via
your network using the hostname go
, you can create memorable custom links such
as go/cl
that redirect to longer target URLs such as
https://github.com/mbland/custom-links
.
You can update the target URLs for links you own, and transfer ownership to other users.
It runs on Node.js and uses Redis as a backing store.
- Install Node.js on your system. This system requires version 4.2 or greater or version 5 or greater. You may wish to first install a version manager such as nvm to manage and install different Node.js versions.
- Install Redis on your system. This system works with version 3, but version 4 or greater is recommended.
- If the Bash shell isn't available on your system, see the Installing Bash section later in this document.
- In the root directory of the application, run the following to install the
necessary npm packages and to ensure that the application is functioning
properly:
$ ./go
- Create app credentials.
- Configure the application.
- To run the server locally for testing and development, save your
configuration as
test-config.json
and run the following command from the root directory of the application:$ ./go serve
- To run a production instance of the server, run the following command
from the root directory of the application, where
config.json
is the path to your configuration file:Alternatively, you can specify the path to the configuration file via the CUSTOM_LINKS_CONFIG_PATH environment variable:$ ./go serve config.json
$ CUSTOM_LINKS_CONFIG_PATH=config.json ./go serve
Right now, only Google OAuth 2.0 is supported, though the Passport-based authentication scheme permits the addition of other authentication providers and strategies.
- On the credentials page of the Google Developer's console, click the Create credentials button and select OAuth client ID.
- Select Web application.
- Fill in the following values:
- Name: "Custom Links server" or whatever you wish
- Authorized JavaScript origins: The root URL of your Custom Links
server. If you're only testing locally, use
http://localhost:3000
- Authorized redirect URIs: The root URL of your Custom Links server
followed by
/auth/callback
. If testing locally, this should behttp://localhost:3000/auth/callback
. You will use this value to set the GOOGLE_CALLBACK_URL configuration variable.
- Click Create.
- Make note of the client ID and client secret values, and use them to set the CUSTOM_LINKS_GOOGLE_CLIENT_ID and CUSTOM_LINKS_GOOGLE_CLIENT_SECRET configuration variables.
You will need to provide a configuration file in JSON format that defines the following required fields:
- PORT: The port number on which the server will listen
- AUTH_PROVIDERS: The name of the authentication provider to use, which
corresponds to one of the file names in
lib/auth
without the.js
suffix- This is a list, since the system may support multiple providers one day; but for now, it should contain only one entry.
- SESSION_SECRET: A secret key used to encrypt user sessions; see the
Environment variables section below. A handy way of
generating this value, if you have Ruby installed on your system:
$ ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'
You must also provide at least one of the following fields:
- users: A list of specific user account names (usually email addresses) that are authorized to access the server. (Case insensitive)
- domains: A list of user domains (i.e. email address domains) that are authorized to access the server. (Case insensitive)
You may define both of these fields if you wish.
The following fields are optional:
- REDIS_PORT: The port your redis-server, if not the default (6379)
- SESSION_MAX_AGE: Maximum age of a user session, in seconds
The following fields are required by the Google OAuth provider (see the Credentials section above):
- GOOGLE_CALLBACK_URL
- GOOGLE_CLIENT_ID
- GOOGLE_CLIENT_SECRET
A complete example looks like the following:
{
"PORT": 3000,
"AUTH_PROVIDERS": [ "google" ],
"REDIS_PORT": 6379,
"SESSION_SECRET": "<session secret>",
"SESSION_MAX_AGE": 3600,
"GOOGLE_CLIENT_ID": "<client ID>",
"GOOGLE_CLIENT_SECRET": "<client secret>",
"GOOGLE_CALLBACK_URL": "http://localhost:3000/auth/callback",
"users": [
"[email protected]"
],
"domains": [
"foo.example.com",
"bar.example.com"
]
}
For local testing, you can define a test-config.json
in the root directory of
the Custom Links instance; ./go serve
will find this file automatically.
For a production instance, you need to provide the path to the configuration via
one of the following methods, where config.json
represents the path to your
configuration file:
$ ./go serve config.json
$ CUSTOM_LINKS_CONFIG_PATH=config.json ./go serve
Any of the string and numeric configuration variables (i.e. not list variables) may be specified by corresponding environment variables prefixed with CUSTOM_LINKS_, for example PORT could be specified as CUSTOM_LINKS_PORT.
Specifically, the following variables should likely be specified as environment variables and not specified in any version-controlled configuration file:
- CUSTOM_LINKS_SESSION_SECRET
- CUSTOM_LINKS_GOOGLE_CLIENT_ID
- CUSTOM_LINKS_GOOGLE_CLIENT_SECRET
If you'd like to experiment with developing the system, start by creating an
alias for the ./go
script called cl
like so:
$ eval "$(./go env cl)"
This alias allows you to run the ./go
script commands from anywhere, with tab
completion for commands that implement it. Begin familiarizing yourself with
cl
commands by running:
$ cl --help
Run cl -h
on any of the following commands for detailed information:
cl test
for server, browser, and end-to-end testscl test server
for server tests onlycl test browser
for browser tests onlycl test end-to-end
for end-to-end tests only
You can add the --coverage
flag to cl test
, cl test server
, or cl test browser
to collect coverage using NYC/Istanbul.
Also see the Caveat: Karma and Safari section below if you plan to test against Apple's Safari browser.
Read through the .config/env.template
file, and consider making a copy as
.config/env.local
and customizing the variables within this copy as described
in the file. Of particular interest are the SELENIUM_BROWSER and
KARMA_BROWSERS variables.
index.js
is the main file used to start the server.
lib/
contains all of the server-side implementation. lib/index.js
is the
entry point. lib/auth
contains Passport-compatible authentication objects.
public/
contains all the front-end code. public/index.html
is the single
HTML file for the application. public/tests/tests.js
contains all the user
interface tests. public/tests/lib.js
contains helper functions for the UI test
suite.
tests/server
contains all of the server-side tests. tests/end-to-end
contains the Selenium-WebDriver tests. tests/helpers
contains various test
helper functions, configurations, and support servers.
scripts/
contains the individual ./go
command scripts.
scripts/go-script-bash
contains the go-script-bash framework upon which
the ./go
script system is built.
If you wish to use the Karma test runner while updating and testing the user interface, make sure to install karma-cli via:
$ npm install -g karma-cli
Now you can run the browser-only tests using one of:
# To keep all browsers running and refreshing automatically on file changes:
$ karma start
# To close all browsers after a single run:
$ karma start --single-run
There are two issues that currently require manual intervention when using Karma with Safari:
- When Safari first opens after
karma start
, the Safari tests will not make progress until Safari is clicked on or otherwise selected as the foreground window. (This doesn't happen withkarma start --single-run
.) - Since Karma doesn't explicitly close browser tabs upon exit, Karma tabs may
still be open the next time it runs, which may cause Karma to
timeout and report a failure. The workaround for now is to open Safari and
close any open Karma tabs in between
karma start
runs.
If you're using a flavor of UNIX (e.g. Linux, OS X), you likely already have a suitable version of Bash already installed and available. If not, use your system's package manager to install it.
On Windows, the Git for Windows, MSYS2 and Cygwin distributions all ship with a version of Bash. On Windows 10, you can also use the Windows Subsystem for Linux.
This software is made available as Open Source software under the ISC License. For the text of the license, see the LICENSE file.