Repository: Tivix/angular-django-registration-auth
Branch: master
Commit: 40c1cc76193a
Files: 59
Total size: 88.2 KB
Directory structure:
gitextract_o9misfkw/
├── .bowerrc
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .jshintrc
├── .travis.yml
├── Gruntfile.js
├── README.md
├── app/
│ ├── .buildignore
│ ├── .htaccess
│ ├── 404.html
│ ├── index.html
│ ├── robots.txt
│ ├── scripts/
│ │ ├── app.js
│ │ ├── controllers/
│ │ │ ├── authrequired.js
│ │ │ ├── login.js
│ │ │ ├── logout.js
│ │ │ ├── main.js
│ │ │ ├── master.js
│ │ │ ├── passwordchange.js
│ │ │ ├── passwordreset.js
│ │ │ ├── passwordresetconfirm.js
│ │ │ ├── register.js
│ │ │ ├── restricted.js
│ │ │ ├── userprofile.js
│ │ │ └── verifyemail.js
│ │ └── services/
│ │ ├── djangoAuth.js
│ │ └── validate.js
│ ├── styles/
│ │ └── main.css
│ └── views/
│ ├── authrequired.html
│ ├── login.html
│ ├── logout.html
│ ├── main.html
│ ├── passwordchange.html
│ ├── passwordreset.html
│ ├── passwordresetconfirm.html
│ ├── register.html
│ ├── restricted.html
│ ├── userprofile.html
│ └── verifyemail.html
├── bower.json
├── karma-e2e.conf.js
├── karma.conf.js
├── package.json
└── test/
├── .jshintrc
├── runner.html
└── spec/
├── controllers/
│ ├── authrequired.js
│ ├── login.js
│ ├── logout.js
│ ├── main.js
│ ├── master.js
│ ├── passwordchange.js
│ ├── passwordreset.js
│ ├── passwordresetconfirm.js
│ ├── register.js
│ ├── restricted.js
│ ├── userprofile.js
│ └── verifyemail.js
└── services/
└── djangoAuth.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .bowerrc
================================================
{
"directory": "app/bower_components"
}
================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .gitattributes
================================================
* text=auto
================================================
FILE: .gitignore
================================================
node_modules
dist
.tmp
.sass-cache
app/bower_components
================================================
FILE: .jshintrc
================================================
{
"node": true,
"browser": true,
"esnext": true,
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": true,
"noarg": true,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": true,
"trailing": true,
"smarttabs": true,
"globals": {
"angular": false
}
}
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- '0.8'
- '0.10'
before_script:
- 'npm install -g bower grunt-cli'
- 'bower install'
================================================
FILE: Gruntfile.js
================================================
// Generated on 2014-04-21 using generator-angular 0.7.1
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
yeoman: {
// configurable paths
app: require('./bower.json').appPath || 'app',
dist: 'dist'
},
// Watches files for changes and runs tasks based on the changed files
watch: {
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true
}
},
jsTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['newer:jshint:test', 'karma']
},
styles: {
files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
tasks: ['newer:copy:styles', 'autoprefixer']
},
gruntfile: {
files: ['Gruntfile.js']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= yeoman.app %>'
]
}
},
test: {
options: {
port: 9001,
base: [
'.tmp',
'test',
'<%= yeoman.app %>'
]
}
},
dist: {
options: {
base: '<%= yeoman.dist %>'
}
}
},
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
],
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/spec/{,*/}*.js']
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git*'
]
}]
},
server: '.tmp'
},
// Add vendor prefixed styles
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the app
'bower-install': {
app: {
html: '<%= yeoman.app %>/index.html',
ignorePath: '<%= yeoman.app %>/'
}
},
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
}
},
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>'
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= yeoman.dist %>']
}
},
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: ['*.html', 'views/{,*/}*.html'],
dest: '<%= yeoman.dist %>'
}]
}
},
// Allow the use of non-minsafe AngularJS files. Automatically makes it
// minsafe compatible so Uglify does not destroy the ng references
ngAnnotate: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
// Replace Google CDN references
cdnify: {
dist: {
html: ['<%= yeoman.dist %>/*.html']
}
},
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'bower_components/**/*',
'images/{,*/}*.{webp}',
'fonts/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [
'copy:styles'
],
test: [
'copy:styles'
],
dist: [
'copy:styles',
'imagemin',
'svgmin'
]
},
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css',
// '<%= yeoman.app %>/styles/{,*/}*.css'
// ]
// }
// }
// },
// uglify: {
// dist: {
// files: {
// '<%= yeoman.dist %>/scripts/scripts.js': [
// '<%= yeoman.dist %>/scripts/scripts.js'
// ]
// }
// }
// },
// concat: {
// dist: {}
// },
// Test settings
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
}
});
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'bower-install',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
});
grunt.registerTask('server', function () {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve']);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'bower-install',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
]);
};
================================================
FILE: README.md
================================================
AngularJS Module for [Django REST Auth](https://github.com/Tivix/django-rest-auth)
==================================================================================
To setup this module as a boilerplate project...
---------------------------------------------------
##### First, clone the repository:
`git clone git@github.com:Tivix/angular-django-registration-auth.git`
##### Change your directory to the cloned project:
`cd angular-django-registration-auth`
##### Then, install the project prerequisites:
`npm install; bower install;`
##### Customize API_URL and use_session to meet your project's requirements:
Go to `app/scripts/services/djangoAuth.js`
###### If using django-rest-auth demo, check out the docs for a list of endpoints:
http://django-rest-auth.readthedocs.org/en/latest/api_endpoints.html
##### Then, serve the Angular Django Registration Auth Demo:
`grunt serve`
To integrate this module into an existing project...
-------------------------------------------------------
##### First, clone the repository:
`git clone git@github.com:Tivix/angular-django-registration-auth.git`
The contents of the `app/scripts` folder can be copied to your own project.
*Exclude controllers and app.js if you do not intend to use the default views/routes. (This will provide API access from the djangoAuth module only.)*
##### Inject the angularDjangoRegistrationAuthApp into your own module.
##### Inject the djangoAuth service into any controllers in which you need programmatic access to Django REST Auth.
##### Customize API_URL and use_session to meet your project's requirements:
Go to `app/scripts/services/djangoAuth.js`
*Alternatively, you can change these settings from a controller by changing the djangoAuth.API_URL and djangoAuth.use_session variables.*
###### Please note:
you will need to include dependencies from bower.json to support the default views/controllers. *They require bootstrap and its dependencies to function correctly.*
If you intend to use the default views/routes, copy the contents of app/views to your own views folder.
Todo: We encourage contributions for these aims...
-----------------------------------------------------
- [ ] Add support for JWT (JSON web tokens)
- [ ] Better support for Bower and Grunt
- [ ] Pick a better name for the module?
================================================
FILE: app/.buildignore
================================================
*.coffee
================================================
FILE: app/.htaccess
================================================
# Apache Configuration File
# (!) Using `.htaccess` files slows down Apache, therefore, if you have access
# to the main server config file (usually called `httpd.conf`), you should add
# this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html.
# ##############################################################################
# # CROSS-ORIGIN RESOURCE SHARING (CORS) #
# ##############################################################################
# ------------------------------------------------------------------------------
# | Cross-domain AJAX requests |
# ------------------------------------------------------------------------------
# Enable cross-origin AJAX requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
# ------------------------------------------------------------------------------
# | CORS-enabled images |
# ------------------------------------------------------------------------------
# Send the CORS header for images when browsers request it.
# https://developer.mozilla.org/en/CORS_Enabled_Image
# http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
# http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(gif|ico|jpe?g|png|svg|svgz|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
# ------------------------------------------------------------------------------
# | Web fonts access |
# ------------------------------------------------------------------------------
# Allow access from all domains for web fonts
<IfModule mod_headers.c>
<FilesMatch "\.(eot|font.css|otf|ttc|ttf|woff)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
# ##############################################################################
# # ERRORS #
# ##############################################################################
# ------------------------------------------------------------------------------
# | 404 error prevention for non-existing redirected folders |
# ------------------------------------------------------------------------------
# Prevent Apache from returning a 404 error for a rewrite if a directory
# with the same name does not exist.
# http://httpd.apache.org/docs/current/content-negotiation.html#multiviews
# http://www.webmasterworld.com/apache/3808792.htm
Options -MultiViews
# ------------------------------------------------------------------------------
# | Custom error messages / pages |
# ------------------------------------------------------------------------------
# You can customize what Apache returns to the client in case of an error (see
# http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.:
ErrorDocument 404 /404.html
# ##############################################################################
# # INTERNET EXPLORER #
# ##############################################################################
# ------------------------------------------------------------------------------
# | Better website experience |
# ------------------------------------------------------------------------------
# Force IE to render pages in the highest available mode in the various
# cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf.
<IfModule mod_headers.c>
Header set X-UA-Compatible "IE=edge"
# `mod_headers` can't match based on the content-type, however, we only
# want to send this header for HTML pages and not for the other resources
<FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
Header unset X-UA-Compatible
</FilesMatch>
</IfModule>
# ------------------------------------------------------------------------------
# | Cookie setting from iframes |
# ------------------------------------------------------------------------------
# Allow cookies to be set from iframes in IE.
# <IfModule mod_headers.c>
# Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
# </IfModule>
# ------------------------------------------------------------------------------
# | Screen flicker |
# ------------------------------------------------------------------------------
# Stop screen flicker in IE on CSS rollovers (this only works in
# combination with the `ExpiresByType` directives for images from below).
# BrowserMatch "MSIE" brokenvary=1
# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
# BrowserMatch "Opera" !brokenvary
# SetEnvIf brokenvary 1 force-no-vary
# ##############################################################################
# # MIME TYPES AND ENCODING #
# ##############################################################################
# ------------------------------------------------------------------------------
# | Proper MIME types for all files |
# ------------------------------------------------------------------------------
<IfModule mod_mime.c>
# Audio
AddType audio/mp4 m4a f4a f4b
AddType audio/ogg oga ogg
# JavaScript
# Normalize to standard type (it's sniffed in IE anyways):
# http://tools.ietf.org/html/rfc4329#section-7.2
AddType application/javascript js jsonp
AddType application/json json
# Video
AddType video/mp4 mp4 m4v f4v f4p
AddType video/ogg ogv
AddType video/webm webm
AddType video/x-flv flv
# Web fonts
AddType application/font-woff woff
AddType application/vnd.ms-fontobject eot
# Browsers usually ignore the font MIME types and sniff the content,
# however, Chrome shows a warning if other MIME types are used for the
# following fonts.
AddType application/x-font-ttf ttc ttf
AddType font/opentype otf
# Make SVGZ fonts work on iPad:
# https://twitter.com/FontSquirrel/status/14855840545
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
# Other
AddType application/octet-stream safariextz
AddType application/x-chrome-extension crx
AddType application/x-opera-extension oex
AddType application/x-shockwave-flash swf
AddType application/x-web-app-manifest+json webapp
AddType application/x-xpinstall xpi
AddType application/xml atom rdf rss xml
AddType image/webp webp
AddType image/x-icon ico
AddType text/cache-manifest appcache manifest
AddType text/vtt vtt
AddType text/x-component htc
AddType text/x-vcard vcf
</IfModule>
# ------------------------------------------------------------------------------
# | UTF-8 encoding |
# ------------------------------------------------------------------------------
# Use UTF-8 encoding for anything served as `text/html` or `text/plain`.
AddDefaultCharset utf-8
# Force UTF-8 for certain file formats.
<IfModule mod_mime.c>
AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml
</IfModule>
# ##############################################################################
# # URL REWRITES #
# ##############################################################################
# ------------------------------------------------------------------------------
# | Rewrite engine |
# ------------------------------------------------------------------------------
# Turning on the rewrite engine and enabling the `FollowSymLinks` option is
# necessary for the following directives to work.
# If your web host doesn't allow the `FollowSymlinks` option, you may need to
# comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the
# performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks
# Also, some cloud hosting services require `RewriteBase` to be set:
# http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site
<IfModule mod_rewrite.c>
Options +FollowSymlinks
# Options +SymLinksIfOwnerMatch
RewriteEngine On
# RewriteBase /
</IfModule>
# ------------------------------------------------------------------------------
# | Suppressing / Forcing the "www." at the beginning of URLs |
# ------------------------------------------------------------------------------
# The same content should never be available under two different URLs especially
# not with and without "www." at the beginning. This can cause SEO problems
# (duplicate content), therefore, you should choose one of the alternatives and
# redirect the other one.
# By default option 1 (no "www.") is activated:
# http://no-www.org/faq.php?q=class_b
# If you'd prefer to use option 2, just comment out all the lines from option 1
# and uncomment the ones from option 2.
# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME!
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Option 1: rewrite www.example.com → example.com
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Option 2: rewrite example.com → www.example.com
# Be aware that the following might not be a good idea if you use "real"
# subdomains for certain parts of your website.
# <IfModule mod_rewrite.c>
# RewriteCond %{HTTPS} !=on
# RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# </IfModule>
# ##############################################################################
# # SECURITY #
# ##############################################################################
# ------------------------------------------------------------------------------
# | Content Security Policy (CSP) |
# ------------------------------------------------------------------------------
# You can mitigate the risk of cross-site scripting and other content-injection
# attacks by setting a Content Security Policy which whitelists trusted sources
# of content for your site.
# The example header below allows ONLY scripts that are loaded from the current
# site's origin (no inline scripts, no CDN, etc). This almost certainly won't
# work as-is for your site!
# To get all the details you'll need to craft a reasonable policy for your site,
# read: http://html5rocks.com/en/tutorials/security/content-security-policy (or
# see the specification: http://w3.org/TR/CSP).
# <IfModule mod_headers.c>
# Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
# <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
# Header unset Content-Security-Policy
# </FilesMatch>
# </IfModule>
# ------------------------------------------------------------------------------
# | File access |
# ------------------------------------------------------------------------------
# Block access to directories without a default document.
# Usually you should leave this uncommented because you shouldn't allow anyone
# to surf through every directory on your server (which may includes rather
# private places like the CMS's directories).
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Block access to hidden files and directories.
# This includes directories used by version control systems such as Git and SVN.
<IfModule mod_rewrite.c>
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]
</IfModule>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Block access to backup and source files.
# These files may be left by some text editors and can pose a great security
# danger when anyone has access to them.
<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
Order allow,deny
Deny from all
Satisfy All
</FilesMatch>
# ------------------------------------------------------------------------------
# | Secure Sockets Layer (SSL) |
# ------------------------------------------------------------------------------
# Rewrite secure requests properly to prevent SSL certificate warnings, e.g.:
# prevent `https://www.example.com` when your certificate only allows
# `https://secure.example.com`.
# <IfModule mod_rewrite.c>
# RewriteCond %{SERVER_PORT} !^443
# RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L]
# </IfModule>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Force client-side SSL redirection.
# If a user types "example.com" in his browser, the above rule will redirect him
# to the secure version of the site. That still leaves a window of opportunity
# (the initial HTTP connection) for an attacker to downgrade or redirect the
# request. The following header ensures that browser will ONLY connect to your
# server via HTTPS, regardless of what the users type in the address bar.
# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/
# <IfModule mod_headers.c>
# Header set Strict-Transport-Security max-age=16070400;
# </IfModule>
# ------------------------------------------------------------------------------
# | Server software information |
# ------------------------------------------------------------------------------
# Avoid displaying the exact Apache version number, the description of the
# generic OS-type and the information about Apache's compiled-in modules.
# ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`!
# ServerTokens Prod
# ##############################################################################
# # WEB PERFORMANCE #
# ##############################################################################
# ------------------------------------------------------------------------------
# | Compression |
# ------------------------------------------------------------------------------
<IfModule mod_deflate.c>
# Force compression for mangled headers.
# http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
# Compress all output labeled with one of the following MIME-types
# (for Apache versions below 2.3.7, you don't need to enable `mod_filter`
# and can remove the `<IfModule mod_filter.c>` and `</IfModule>` lines
# as `AddOutputFilterByType` is still in the core directives).
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/atom+xml \
application/javascript \
application/json \
application/rss+xml \
application/vnd.ms-fontobject \
application/x-font-ttf \
application/x-web-app-manifest+json \
application/xhtml+xml \
application/xml \
font/opentype \
image/svg+xml \
image/x-icon \
text/css \
text/html \
text/plain \
text/x-component \
text/xml
</IfModule>
</IfModule>
# ------------------------------------------------------------------------------
# | Content transformations |
# ------------------------------------------------------------------------------
# Prevent some of the mobile network providers from modifying the content of
# your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5.
# <IfModule mod_headers.c>
# Header set Cache-Control "no-transform"
# </IfModule>
# ------------------------------------------------------------------------------
# | ETag removal |
# ------------------------------------------------------------------------------
# Since we're sending far-future expires headers (see below), ETags can
# be removed: http://developer.yahoo.com/performance/rules.html#etags.
# `FileETag None` is not enough for every server.
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None
# ------------------------------------------------------------------------------
# | Expires headers (for better cache control) |
# ------------------------------------------------------------------------------
# The following expires headers are set pretty far in the future. If you don't
# control versioning with filename-based cache busting, consider lowering the
# cache time for resources like CSS and JS to something like 1 week.
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 year"
# Data interchange
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
# Favicon (cannot be renamed!)
ExpiresByType image/x-icon "access plus 1 week"
# HTML components (HTCs)
ExpiresByType text/x-component "access plus 1 month"
# HTML
ExpiresByType text/html "access plus 0 seconds"
# JavaScript
ExpiresByType application/javascript "access plus 1 year"
# Manifest files
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
ExpiresByType text/cache-manifest "access plus 0 seconds"
# Media
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# Web feeds
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
# Web fonts
ExpiresByType application/font-woff "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
</IfModule>
# ------------------------------------------------------------------------------
# | Filename-based cache busting |
# ------------------------------------------------------------------------------
# If you're not using a build process to manage your filename version revving,
# you might want to consider enabling the following directives to route all
# requests such as `/css/style.12345.css` to `/css/style.css`.
# To understand why this is important and a better idea than `*.css?v231`, read:
# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring
# <IfModule mod_rewrite.c>
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]
# </IfModule>
# ------------------------------------------------------------------------------
# | File concatenation |
# ------------------------------------------------------------------------------
# Allow concatenation from within specific CSS and JS files, e.g.:
# Inside of `script.combined.js` you could have
# <!--#include file="libs/jquery.js" -->
# <!--#include file="plugins/jquery.idletimer.js" -->
# and they would be included into this single file.
# <IfModule mod_include.c>
# <FilesMatch "\.combined\.js$">
# Options +Includes
# AddOutputFilterByType INCLUDES application/javascript application/json
# SetOutputFilter INCLUDES
# </FilesMatch>
# <FilesMatch "\.combined\.css$">
# Options +Includes
# AddOutputFilterByType INCLUDES text/css
# SetOutputFilter INCLUDES
# </FilesMatch>
# </IfModule>
# ------------------------------------------------------------------------------
# | Persistent connections |
# ------------------------------------------------------------------------------
# Allow multiple requests to be sent over the same TCP connection:
# http://httpd.apache.org/docs/current/en/mod/core.html#keepalive.
# Enable if you serve a lot of static content but, be aware of the
# possible disadvantages!
# <IfModule mod_headers.c>
# Header set Connection Keep-Alive
# </IfModule>
================================================
FILE: app/404.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Page Not Found :(</title>
<style>
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
html {
padding: 30px 10px;
font-size: 20px;
line-height: 1.4;
color: #737373;
background: #f0f0f0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
input {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
body {
max-width: 500px;
_width: 500px;
padding: 30px 20px 50px;
border: 1px solid #b3b3b3;
border-radius: 4px;
margin: 0 auto;
box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;
background: #fcfcfc;
}
h1 {
margin: 0 10px;
font-size: 50px;
text-align: center;
}
h1 span {
color: #bbb;
}
h3 {
margin: 1.5em 0 0.5em;
}
p {
margin: 1em 0;
}
ul {
padding: 0 0 0 40px;
margin: 1em 0;
}
.container {
max-width: 380px;
_width: 380px;
margin: 0 auto;
}
/* google search */
#goog-fixurl ul {
list-style: none;
padding: 0;
margin: 0;
}
#goog-fixurl form {
margin: 0;
}
#goog-wm-qt,
#goog-wm-sb {
border: 1px solid #bbb;
font-size: 16px;
line-height: normal;
vertical-align: top;
color: #444;
border-radius: 2px;
}
#goog-wm-qt {
width: 220px;
height: 20px;
padding: 5px;
margin: 5px 10px 0 0;
box-shadow: inset 0 1px 1px #ccc;
}
#goog-wm-sb {
display: inline-block;
height: 32px;
padding: 0 10px;
margin: 5px 0 0;
white-space: nowrap;
cursor: pointer;
background-color: #f5f5f5;
background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
*overflow: visible;
*display: inline;
*zoom: 1;
}
#goog-wm-sb:hover,
#goog-wm-sb:focus {
border-color: #aaa;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
background-color: #f8f8f8;
}
#goog-wm-qt:hover,
#goog-wm-qt:focus {
border-color: #105cb6;
outline: 0;
color: #222;
}
input::-moz-focus-inner {
padding: 0;
border: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Not found <span>:(</span></h1>
<p>Sorry, but the page you were trying to view does not exist.</p>
<p>It looks like this was the result of either:</p>
<ul>
<li>a mistyped address</li>
<li>an out-of-date link</li>
</ul>
<script>
var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),GOOG_FIXURL_SITE = location.host;
</script>
<script src="//linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
</div>
</body>
</html>
================================================
FILE: app/index.html
================================================
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css styles/vendor.css -->
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<!-- endbower -->
<!-- endbuild -->
<!-- build:css({.tmp,app}) styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
</head>
<body ng-app="angularDjangoRegistrationAuthApp" ng-controller="MasterCtrl">
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div class="container">
<div class="header">
<ul class="nav nav-pills pull-right">
<li class="active"><a ng-href="#/">Home</a></li>
</ul>
<h3 class="text-muted">Angular Django Registration Auth Demo</h3>
</div>
<!-- Add your site or application content here -->
<div ng-view=""></div>
</div>
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-X');
ga('send', 'pageview');
</script>
<!--[if lt IE 9]>
<script src="bower_components/es5-shim/es5-shim.js"></script>
<script src="bower_components/json3/lib/json3.min.js"></script>
<![endif]-->
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/controllers/register.js"></script>
<script src="scripts/controllers/passwordreset.js"></script>
<script src="scripts/controllers/passwordresetconfirm.js"></script>
<script src="scripts/controllers/login.js"></script>
<script src="scripts/controllers/verifyemail.js"></script>
<script src="scripts/controllers/logout.js"></script>
<script src="scripts/controllers/userprofile.js"></script>
<script src="scripts/controllers/passwordchange.js"></script>
<script src="scripts/services/djangoAuth.js"></script>
<script src="scripts/services/validate.js"></script>
<script src="scripts/controllers/master.js"></script>
<script src="scripts/controllers/restricted.js"></script>
<script src="scripts/controllers/authrequired.js"></script>
<!-- endbuild -->
</body>
</html>
================================================
FILE: app/robots.txt
================================================
# robotstxt.org
User-agent: *
================================================
FILE: app/scripts/app.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/register', {
templateUrl: 'views/register.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/passwordReset', {
templateUrl: 'views/passwordreset.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/passwordResetConfirm/:firstToken/:passwordResetToken', {
templateUrl: 'views/passwordresetconfirm.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/login', {
templateUrl: 'views/login.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/verifyEmail/:emailVerificationToken', {
templateUrl: 'views/verifyemail.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/logout', {
templateUrl: 'views/logout.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/userProfile', {
templateUrl: 'views/userprofile.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/passwordChange', {
templateUrl: 'views/passwordchange.html',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/restricted', {
templateUrl: 'views/restricted.html',
controller: 'RestrictedCtrl',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus();
}],
}
})
.when('/authRequired', {
templateUrl: 'views/authrequired.html',
controller: 'AuthrequiredCtrl',
resolve: {
authenticated: ['djangoAuth', function(djangoAuth){
return djangoAuth.authenticationStatus(true);
}],
}
})
.otherwise({
redirectTo: '/'
});
})
.run(function(djangoAuth){
djangoAuth.initialize('//127.0.0.1:8000/rest-auth', false);
});
================================================
FILE: app/scripts/controllers/authrequired.js
================================================
'use strict';
/**
* @ngdoc function
* @name angularDjangoRegistrationAuthApp.controller:AuthrequiredCtrl
* @description
* # AuthrequiredCtrl
* Controller of the angularDjangoRegistrationAuthApp
*/
angular.module('angularDjangoRegistrationAuthApp')
.controller('AuthrequiredCtrl', function ($scope) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
});
================================================
FILE: app/scripts/controllers/login.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('LoginCtrl', function ($scope, $location, djangoAuth, Validate) {
$scope.model = {'username':'','password':''};
$scope.complete = false;
$scope.login = function(formData){
$scope.errors = [];
Validate.form_validation(formData,$scope.errors);
if(!formData.$invalid){
djangoAuth.login($scope.model.username, $scope.model.password)
.then(function(data){
// success case
$location.path("/");
},function(data){
// error case
$scope.errors = data;
});
}
}
});
================================================
FILE: app/scripts/controllers/logout.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('LogoutCtrl', function ($scope, $location, djangoAuth) {
djangoAuth.logout();
});
================================================
FILE: app/scripts/controllers/main.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('MainCtrl', function ($scope, $cookies, $location, djangoAuth) {
$scope.login = function(){
djangoAuth.login(prompt('Username'),prompt('password'))
.then(function(data){
handleSuccess(data);
},handleError);
}
$scope.logout = function(){
djangoAuth.logout()
.then(handleSuccess,handleError);
}
$scope.resetPassword = function(){
djangoAuth.resetPassword(prompt('Email'))
.then(handleSuccess,handleError);
}
$scope.register = function(){
djangoAuth.register(prompt('Username'),prompt('Password'),prompt('Email'))
.then(handleSuccess,handleError);
}
$scope.verify = function(){
djangoAuth.verify(prompt("Please enter verification code"))
.then(handleSuccess,handleError);
}
$scope.goVerify = function(){
$location.path("/verifyEmail/"+prompt("Please enter verification code"));
}
$scope.changePassword = function(){
djangoAuth.changePassword(prompt("Password"), prompt("Repeat Password"))
.then(handleSuccess,handleError);
}
$scope.profile = function(){
djangoAuth.profile()
.then(handleSuccess,handleError);
}
$scope.updateProfile = function(){
djangoAuth.updateProfile({'first_name': prompt("First Name"), 'last_name': prompt("Last Name"), 'email': prompt("Email")})
.then(handleSuccess,handleError);
}
$scope.confirmReset = function(){
djangoAuth.confirmReset(prompt("Code 1"), prompt("Code 2"), prompt("Password"), prompt("Repeat Password"))
.then(handleSuccess,handleError);
}
$scope.goConfirmReset = function(){
$location.path("/passwordResetConfirm/"+prompt("Code 1")+"/"+prompt("Code 2"))
}
var handleSuccess = function(data){
$scope.response = data;
}
var handleError = function(data){
$scope.response = data;
}
$scope.show_login = true;
$scope.$on("djangoAuth.logged_in", function(data){
$scope.show_login = false;
});
$scope.$on("djangoAuth.logged_out", function(data){
$scope.show_login = true;
});
});
================================================
FILE: app/scripts/controllers/master.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('MasterCtrl', function ($scope, $location, djangoAuth) {
// Assume user is not logged in until we hear otherwise
$scope.authenticated = false;
// Wait for the status of authentication, set scope var to true if it resolves
djangoAuth.authenticationStatus(true).then(function(){
$scope.authenticated = true;
});
// Wait and respond to the logout event.
$scope.$on('djangoAuth.logged_out', function() {
$scope.authenticated = false;
});
// Wait and respond to the log in event.
$scope.$on('djangoAuth.logged_in', function() {
$scope.authenticated = true;
});
// If the user attempts to access a restricted page, redirect them back to the main page.
$scope.$on('$routeChangeError', function(ev, current, previous, rejection){
console.error("Unable to change routes. Error: ", rejection)
$location.path('/restricted').replace();
});
});
================================================
FILE: app/scripts/controllers/passwordchange.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('PasswordchangeCtrl', function ($scope, djangoAuth, Validate) {
$scope.model = {'new_password1':'','new_password2':''};
$scope.complete = false;
$scope.changePassword = function(formData){
$scope.errors = [];
Validate.form_validation(formData,$scope.errors);
if(!formData.$invalid){
djangoAuth.changePassword($scope.model.new_password1, $scope.model.new_password2)
.then(function(data){
// success case
$scope.complete = true;
},function(data){
// error case
$scope.errors = data;
});
}
}
});
================================================
FILE: app/scripts/controllers/passwordreset.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('PasswordresetCtrl', function ($scope, djangoAuth, Validate) {
$scope.model = {'email':''};
$scope.complete = false;
$scope.resetPassword = function(formData){
$scope.errors = [];
Validate.form_validation(formData,$scope.errors);
if(!formData.$invalid){
djangoAuth.resetPassword($scope.model.email)
.then(function(data){
// success case
$scope.complete = true;
},function(data){
// error case
$scope.errors = data;
});
}
}
});
================================================
FILE: app/scripts/controllers/passwordresetconfirm.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('PasswordresetconfirmCtrl', function ($scope, $routeParams, djangoAuth, Validate) {
$scope.model = {'new_password1':'','new_password2':''};
$scope.complete = false;
$scope.confirmReset = function(formData){
$scope.errors = [];
Validate.form_validation(formData,$scope.errors);
if(!formData.$invalid){
djangoAuth.confirmReset($routeParams['firstToken'], $routeParams['passwordResetToken'], $scope.model.new_password1, $scope.model.new_password2)
.then(function(data){
// success case
$scope.complete = true;
},function(data){
// error case
$scope.errors = data;
});
}
}
});
================================================
FILE: app/scripts/controllers/register.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('RegisterCtrl', function ($scope, djangoAuth, Validate) {
$scope.model = {'username':'','password':'','email':''};
$scope.complete = false;
$scope.register = function(formData){
$scope.errors = [];
Validate.form_validation(formData,$scope.errors);
if(!formData.$invalid){
djangoAuth.register($scope.model.username,$scope.model.password1,$scope.model.password2,$scope.model.email)
.then(function(data){
// success case
$scope.complete = true;
},function(data){
// error case
$scope.errors = data;
});
}
}
});
================================================
FILE: app/scripts/controllers/restricted.js
================================================
'use strict';
/**
* @ngdoc function
* @name angularDjangoRegistrationAuthApp.controller:RestrictedCtrl
* @description
* # RestrictedCtrl
* Controller of the angularDjangoRegistrationAuthApp
*/
angular.module('angularDjangoRegistrationAuthApp')
.controller('RestrictedCtrl', function ($scope, $location) {
$scope.$on('djangoAuth.logged_in', function() {
$location.path('/');
});
});
================================================
FILE: app/scripts/controllers/userprofile.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('UserprofileCtrl', function ($scope, djangoAuth, Validate) {
$scope.model = {'first_name':'','last_name':'','email':''};
$scope.complete = false;
djangoAuth.profile().then(function(data){
$scope.model = data;
});
$scope.updateProfile = function(formData, model){
$scope.errors = [];
Validate.form_validation(formData,$scope.errors);
if(!formData.$invalid){
djangoAuth.updateProfile(model)
.then(function(data){
// success case
$scope.complete = true;
},function(data){
// error case
$scope.error = data;
});
}
}
});
================================================
FILE: app/scripts/controllers/verifyemail.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.controller('VerifyemailCtrl', function ($scope, $routeParams, djangoAuth) {
djangoAuth.verify($routeParams["emailVerificationToken"]).then(function(data){
$scope.success = true;
},function(data){
$scope.failure = false;
});
});
================================================
FILE: app/scripts/services/djangoAuth.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.service('djangoAuth', function djangoAuth($q, $http, $cookies, $rootScope) {
// AngularJS will instantiate a singleton by calling "new" on this function
var service = {
/* START CUSTOMIZATION HERE */
// Change this to point to your Django REST Auth API
// e.g. /api/rest-auth (DO NOT INCLUDE ENDING SLASH)
'API_URL': '',
// Set use_session to true to use Django sessions to store security token.
// Set use_session to false to store the security token locally and transmit it as a custom header.
'use_session': true,
/* END OF CUSTOMIZATION */
'authenticated': null,
'authPromise': null,
'request': function(args) {
// Let's retrieve the token from the cookie, if available
if($cookies.token){
$http.defaults.headers.common.Authorization = 'Token ' + $cookies.token;
}
// Continue
params = args.params || {}
args = args || {};
var deferred = $q.defer(),
url = this.API_URL + args.url,
method = args.method || "GET",
params = params,
data = args.data || {};
// Fire the request, as configured.
$http({
url: url,
withCredentials: this.use_session,
method: method.toUpperCase(),
headers: {'X-CSRFToken': $cookies['csrftoken']},
params: params,
data: data
})
.success(angular.bind(this,function(data, status, headers, config) {
deferred.resolve(data, status);
}))
.error(angular.bind(this,function(data, status, headers, config) {
console.log("error syncing with: " + url);
// Set request status
if(data){
data.status = status;
}
if(status == 0){
if(data == ""){
data = {};
data['status'] = 0;
data['non_field_errors'] = ["Could not connect. Please try again."];
}
// or if the data is null, then there was a timeout.
if(data == null){
// Inject a non field error alerting the user
// that there's been a timeout error.
data = {};
data['status'] = 0;
data['non_field_errors'] = ["Server timed out. Please try again."];
}
}
deferred.reject(data, status, headers, config);
}));
return deferred.promise;
},
'register': function(username,password1,password2,email,more){
var data = {
'username':username,
'password1':password1,
'password2':password2,
'email':email
}
data = angular.extend(data,more);
return this.request({
'method': "POST",
'url': "/registration/",
'data' :data
});
},
'login': function(username,password){
var djangoAuth = this;
return this.request({
'method': "POST",
'url': "/login/",
'data':{
'username':username,
'password':password
}
}).then(function(data){
if(!djangoAuth.use_session){
$http.defaults.headers.common.Authorization = 'Token ' + data.key;
$cookies.token = data.key;
}
djangoAuth.authenticated = true;
$rootScope.$broadcast("djangoAuth.logged_in", data);
});
},
'logout': function(){
var djangoAuth = this;
return this.request({
'method': "POST",
'url': "/logout/"
}).then(function(data){
delete $http.defaults.headers.common.Authorization;
delete $cookies.token;
djangoAuth.authenticated = false;
$rootScope.$broadcast("djangoAuth.logged_out");
});
},
'changePassword': function(password1,password2){
return this.request({
'method': "POST",
'url': "/password/change/",
'data':{
'new_password1':password1,
'new_password2':password2
}
});
},
'resetPassword': function(email){
return this.request({
'method': "POST",
'url': "/password/reset/",
'data':{
'email':email
}
});
},
'profile': function(){
return this.request({
'method': "GET",
'url': "/user/"
});
},
'updateProfile': function(data){
return this.request({
'method': "PATCH",
'url': "/user/",
'data':data
});
},
'verify': function(key){
return this.request({
'method': "POST",
'url': "/registration/verify-email/",
'data': {'key': key}
});
},
'confirmReset': function(uid,token,password1,password2){
return this.request({
'method': "POST",
'url': "/password/reset/confirm/",
'data':{
'uid': uid,
'token': token,
'new_password1':password1,
'new_password2':password2
}
});
},
'authenticationStatus': function(restrict, force){
// Set restrict to true to reject the promise if not logged in
// Set to false or omit to resolve when status is known
// Set force to true to ignore stored value and query API
restrict = restrict || false;
force = force || false;
if(this.authPromise == null || force){
this.authPromise = this.request({
'method': "GET",
'url': "/user/"
})
}
var da = this;
var getAuthStatus = $q.defer();
if(this.authenticated != null && !force){
// We have a stored value which means we can pass it back right away.
if(this.authenticated == false && restrict){
getAuthStatus.reject("User is not logged in.");
}else{
getAuthStatus.resolve();
}
}else{
// There isn't a stored value, or we're forcing a request back to
// the API to get the authentication status.
this.authPromise.then(function(){
da.authenticated = true;
getAuthStatus.resolve();
},function(){
da.authenticated = false;
if(restrict){
getAuthStatus.reject("User is not logged in.");
}else{
getAuthStatus.resolve();
}
});
}
return getAuthStatus.promise;
},
'initialize': function(url, sessions){
this.API_URL = url;
this.use_session = sessions;
return this.authenticationStatus();
}
}
return service;
});
================================================
FILE: app/scripts/services/validate.js
================================================
'use strict';
angular.module('angularDjangoRegistrationAuthApp')
.service('Validate', function Validate() {
return {
'message': {
'minlength': 'This value is not long enough.',
'maxlength': 'This value is too long.',
'email': 'A properly formatted email address is required.',
'required': 'This field is required.'
},
'more_messages': {
'demo': {
'required': 'Here is a sample alternative required message.'
}
},
'check_more_messages': function(name,error){
return (this.more_messages[name] || [])[error] || null;
},
validation_messages: function(field,form,error_bin){
var messages = [];
for(var e in form[field].$error){
if(form[field].$error[e]){
var special_message = this.check_more_messages(field,e);
if(special_message){
messages.push(special_message);
}else if(this.message[e]){
messages.push(this.message[e]);
}else{
messages.push("Error: " + e)
}
}
}
var deduped_messages = [];
angular.forEach(messages, function(el, i){
if(deduped_messages.indexOf(el) === -1) deduped_messages.push(el);
});
if(error_bin){
error_bin[field] = deduped_messages;
}
},
'form_validation': function(form,error_bin){
for(var field in form){
if(field.substr(0,1) != "$"){
this.validation_messages(field,form,error_bin);
}
}
}
}
});
================================================
FILE: app/styles/main.css
================================================
/* Space out content a bit */
body {
padding-top: 20px;
padding-bottom: 20px;
}
/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
padding-left: 15px;
padding-right: 15px;
}
/* Custom page header */
.header {
border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
margin-top: 0;
margin-bottom: 0;
line-height: 40px;
padding-bottom: 19px;
}
/* Custom page footer */
.footer {
padding-top: 19px;
color: #777;
border-top: 1px solid #e5e5e5;
}
/* Customize container */
@media (min-width: 768px) {
.container {
max-width: 730px;
}
}
.container-narrow > hr {
margin: 30px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 40px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
/* Remove the padding we set earlier */
.header,
.marketing,
.footer {
padding-left: 0;
padding-right: 0;
}
/* Space out the masthead */
.header {
margin-bottom: 30px;
}
/* Remove the bottom border on the jumbotron for visual effect */
.jumbotron {
border-bottom: 0;
}
}
================================================
FILE: app/views/authrequired.html
================================================
<p>This is a restricted view. You must be authenticated to view it.</p>
================================================
FILE: app/views/login.html
================================================
<div id="login_view" ng-controller="LoginCtrl">
<form role="form" ng-submit="login(loginForm)" name="loginForm" novalidate>
<div class="form-group">
<label for="id_username">Username</label>
<input name="username" id="id_username" type="text" ng-model="model.username" placeholder="Username" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.username">{{error}}</div>
<div class="form-group">
<label for="id_password">Password</label>
<input name="password" id="id_password" type="password" ng-model="model.password" placeholder="Password" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.password">{{error}}</div>
<div class="alert alert-danger" ng-repeat="error in errors.non_field_errors">{{error}}</div>
<div class="alert alert-danger" ng-if="error">{{error}}</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
================================================
FILE: app/views/logout.html
================================================
<div id="logout_view" ng-controller="LogoutCtrl">
<div class="alert alert-info">You have logged out.</div>
</div>
================================================
FILE: app/views/main.html
================================================
<h4>Routes</h4>
<p>
<a ng-hide="authenticated" href="#/login" class="btn btn-primary">Login</a>
<a ng-hide="authenticated" href="#/passwordReset" class="btn btn-primary">Send Password Reset</a>
<a ng-hide="authenticated" ng-click="goConfirmReset()" class="btn btn-primary">Confirm Password Reset</a>
</p>
<p>
<a ng-show="authenticated" href="#/logout" class="btn btn-primary">Logout</a>
<a ng-hide="authenticated" ng-href="#/register" class="btn btn-primary">Register</a>
<a ng-click="goVerify()" class="btn btn-primary">Verify Email</a>
<a ng-show="authenticated" href="#/passwordChange" class="btn btn-primary">Change Password</a>
<a ng-show="authenticated" href="#/userProfile" class="btn btn-primary">Profile</a>
<a href="#/authRequired" class="btn btn-primary">Restricted Page</a>
</p>
<hr/>
<h4>Kitchen Sink Demo</h4>
<div style="margin-bottom:25px;">
<div style="margin-bottom:15px;">
<button ng-hide="authenticated" ng-click="login()" class="btn btn-primary">Login</button>
<button ng-show="authenticated" ng-click="logout()" class="btn btn-primary">Logout</button>
<button ng-hide="authenticated" ng-click="resetPassword()" class="btn btn-primary">Send Password Reset</button>
<button ng-hide="authenticated" ng-click="confirmReset()" class="btn btn-primary">Confirm Password Reset</button>
<button ng-hide="authenticated" ng-click="register()" class="btn btn-primary">Register</button>
<button ng-click="verify()" class="btn btn-primary">Verify Email</button>
<button ng-show="authenticated" ng-click="changePassword()" class="btn btn-primary">Change Password</button>
<button ng-show="authenticated" ng-click="profile()" class="btn btn-primary">Get Profile</button>
<button ng-show="authenticated" ng-click="updateProfile()" class="btn btn-primary">Update Profile</button>
</div>
<p><textarea style="width:90%;height:200px;">{{response}}</textarea></p>
</div>
<hr/>
<h4>ngInclude Demo - Login</h4>
<div ng-if="show_login" ng-include="'views/login.html'"></div>
<div ng-if="!show_login" class="alert alert-info">You have logged in.</div>
<div class="footer">
<p>Tivix</p>
</div>
================================================
FILE: app/views/passwordchange.html
================================================
<div id="passwordChange_view" ng-controller="PasswordchangeCtrl">
<div ng-if="complete == false">
<form role="form" ng-submit="changePassword(changePasswordForm)" name="changePasswordForm" ng-if="authenticated" novalidate>
<div class="form-group">
<label for="id_password1">New Password</label>
<input name="new_password1" id="id_password1" type="password" ng-model="model.new_password1" placeholder="New Password" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.new_password1">{{error}}</div>
<div class="form-group">
<label for="id_password2">Repeat Password</label>
<input name="new_password2" id="id_password2" type="password" ng-model="model.new_password2" placeholder="Repeat Password" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.new_password2">{{error}}</div>
<button ng-show="authenticated" type="submit" class="btn btn-primary">Change Password</button>
</form>
<div class="alert alert-warning" ng-if="authenticated != true">You need to be logged in to do this!</div>
</div>
<div ng-if="complete == true">
<div class="alert alert-success">You have changed your password.</div>
</div>
</div>
================================================
FILE: app/views/passwordreset.html
================================================
<div id="passwordReset_view" ng-controller="PasswordresetCtrl">
<div ng-if="complete == false">
<form role="form" ng-if="authenticated != true" name="passwordResetForm" ng-submit="resetPassword(passwordResetForm)" novalidate>
<div class="form-group">
<label for="id_email">Email</label>
<input name="email" id="id_email" type="text" ng-model="model.email" placeholder="Email" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.email">{{error}}</div>
<button ng-hide="authenticated" type="submit" class="btn btn-primary">Reset Password</button>
</form>
<p ng-if="authenticated">You are already logged in! You don't need to reset your password.</p>
</div>
<div ng-if="complete == true">
<div class="alert alert-success">You should receive an email shortly with instructions on how to reset your account password.</div>
</div>
</div>
================================================
FILE: app/views/passwordresetconfirm.html
================================================
<div id="passwordResetConfirm_view" ng-controller="PasswordresetconfirmCtrl">
<div ng-if="complete == false">
<form role="form" ng-if="authenticated != true" ng-submit="confirmReset(confirmResetForm)" name="confirmResetForm" novalidate>
<div class="form-group">
<label for="id_password1">New Password</label>
<input name="password1" id="id_password1" type="password" ng-model="model.new_password1" placeholder="New Password" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.password1">{{error}}</div>
<div class="form-group">
<label for="id_password2">Repeat Password</label>
<input name="password2" id="id_password2" type="password" ng-model="model.new_password2" placeholder="Repeat Password" class="form-control" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.password2">{{error}}</div>
<button type="submit" ng-hide="authenticated" class="btn btn-primary">Reset Password</button>
</form>
<p ng-if="authenticated">You are already logged in! You don't need to reset your password.</p>
</div>
<div ng-if="complete == true">
<div class="alert alert-success">You have changed your password.</div>
</div>
</div>
================================================
FILE: app/views/register.html
================================================
<div id="register_view" ng-controller="RegisterCtrl">
<div ng-if="complete == false">
<form role="form" ng-if="authenticated != true" name="registerForm" ng-submit="register(registerForm)" novalidate>
<div class="form-group">
<label for="id_username">Username</label>
<input name="username" id="id_username" class="form-control" type="text" ng-model="model.username" placeholder="Username" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.username">{{error}}</div>
<div class="form-group">
<label for="id_password">Password</label>
<input name="password1" id="id_password1" class="form-control" type="password" ng-model="model.password1" placeholder="Password" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.password1">{{error}}</div>
<div class="form-group">
<label for="id_password">Repeat Password</label>
<input name="password" id="id_password2" class="form-control" type="password" ng-model="model.password2" placeholder="Repeat Password" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.password2">{{error}}</div>
<div class="form-group">
<label for="id_email">Email</label>
<input name="email" id="id_email" class="form-control" type="email" ng-model="model.email" placeholder="Email" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.email">{{error}}</div>
<button ng-hide="authenticated" type="submit" class="btn btn-primary">Register</button>
</form>
<p ng-if="authenticated">You are already logged in! You don't need to register.</p>
</div>
<div ng-if="complete == true">
<div class="alert alert-success">Great! You've just registered. You should receive an email shortly with instructions on how to activate your account.</div>
</div>
</div>
================================================
FILE: app/views/restricted.html
================================================
<p>You have attempted to access a restricted page. Please login to continue.</p>
<div ng-include="'views/login.html'"></div>
================================================
FILE: app/views/userprofile.html
================================================
<div id="userProfile_view" ng-controller="UserprofileCtrl">
<div ng-if="complete == false">
<form role="form" ng-if="authenticated" name="userProfileForm" ng-submit="updateProfile(userProfileForm, model)" novalidate>
<div class="form-group">
<label for="id_first_name">First Name</label>
<input name="first_name" id="id_first_name" class="form-control" type="text" ng-model="model.first_name" placeholder="First Name" />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.first_name">{{error}}</div>
<div class="form-group">
<label for="id_last_name">Last Name</label>
<input name="last_name" id="id_last_name" class="form-control" type="text" ng-model="model.last_name" placeholder="Last Name" />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.last_name">{{error}}</div>
<div class="form-group">
<label for="id_email">Email</label>
<input name="email" id="id_email" class="form-control" type="email" ng-model="model.email" placeholder="Email" required />
</div>
<div class="alert alert-danger" ng-repeat="error in errors.email">{{error}}</div>
<button type="submit" ng-show="authenticated" class="btn btn-primary">Update Profile</button>
</form>
<div class="alert alert-warning" ng-if="authenticated == false">You need to be logged in to do this.</div>
</div>
<div ng-if="complete == true">
<div class="alert alert-success">You have updated your profile.</div>
</div>
</div>
================================================
FILE: app/views/verifyemail.html
================================================
<div id="verifyEmail_view" ng-controller="VerifyemailCtrl">
<div ng-if="success" class="alert alert-success">You have successfully verified your email address.</div>
<div ng-if="failure" class="alert alert-warning">Sorry, there's been an error.</div>
</div>
================================================
FILE: bower.json
================================================
{
"name": "angular-django-registration-auth",
"version": "0.0.0",
"dependencies": {
"angular": "1.2.16",
"json3": "~3.2.6",
"es5-shim": "~2.1.0",
"jquery": "~1.10.2",
"bootstrap": "~3.1.1",
"angular-resource": "1.2.16",
"angular-cookies": "1.2.16",
"angular-sanitize": "1.2.16",
"angular-route": "1.2.16"
},
"devDependencies": {
"angular-mocks": "1.2.16",
"angular-scenario": "1.2.16"
}
}
================================================
FILE: karma-e2e.conf.js
================================================
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['ng-scenario'],
// list of files / patterns to load in the browser
files: [
'test/e2e/**/*.js'
],
// list of files / patterns to exclude
exclude: [],
// web server port
port: 8080,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
// Uncomment the following lines if you are using grunt's server to run the tests
// proxies: {
// '/': 'http://localhost:9000/'
// },
// URL root prevent conflicts with the site root
// urlRoot: '_karma_'
});
};
================================================
FILE: karma.conf.js
================================================
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'app/bower_components/angular/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-cookies/angular-cookies.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-route/angular-route.js',
'app/scripts/*.js',
'app/scripts/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
],
// list of files / patterns to exclude
exclude: [],
// web server port
port: 8080,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
================================================
FILE: package.json
================================================
{
"name": "angulardjangoregistrationauth",
"version": "0.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.4",
"grunt-autoprefixer": "~0.4.0",
"grunt-bower-install": "~0.7.0",
"grunt-concurrent": "~0.4.1",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.5.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-cssmin": "~0.7.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-imagemin": "~0.3.0",
"grunt-contrib-jshint": "~0.7.1",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-watch": "~0.5.2",
"grunt-google-cdn": "~0.2.0",
"grunt-newer": "~0.5.4",
"grunt-ng-annotate": "~0.10.0",
"grunt-rev": "~0.1.0",
"grunt-svgmin": "~0.2.0",
"grunt-usemin": "~2.0.0",
"jshint-stylish": "~0.1.3",
"load-grunt-tasks": "~0.2.0",
"time-grunt": "~0.2.1"
},
"engines": {
"node": ">=0.8.0"
},
"scripts": {
"test": "grunt test"
}
}
================================================
FILE: test/.jshintrc
================================================
{
"node": true,
"browser": true,
"esnext": true,
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": true,
"noarg": true,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": true,
"trailing": true,
"smarttabs": true,
"globals": {
"after": false,
"afterEach": false,
"angular": false,
"before": false,
"beforeEach": false,
"browser": false,
"describe": false,
"expect": false,
"inject": false,
"it": false,
"jasmine": false,
"spyOn": false
}
}
================================================
FILE: test/runner.html
================================================
<!doctype html>
<html lang="en">
<head>
<title>End2end Test Runner</title>
<script src="vendor/angular-scenario.js" ng-autotest></script>
<script src="scenarios.js"></script>
</head>
<body>
</body>
</html>
================================================
FILE: test/spec/controllers/authrequired.js
================================================
'use strict';
describe('Controller: AuthrequiredCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var AuthrequiredCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
AuthrequiredCtrl = $controller('AuthrequiredCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/login.js
================================================
'use strict';
describe('Controller: LoginCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var LoginCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
LoginCtrl = $controller('LoginCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/logout.js
================================================
'use strict';
describe('Controller: LogoutCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var LogoutCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
LogoutCtrl = $controller('LogoutCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/main.js
================================================
'use strict';
describe('Controller: MainCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var MainCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('MainCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/master.js
================================================
'use strict';
describe('Controller: MasterCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var MasterCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MasterCtrl = $controller('MasterCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/passwordchange.js
================================================
'use strict';
describe('Controller: PasswordchangeCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var PasswordchangeCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
PasswordchangeCtrl = $controller('PasswordchangeCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/passwordreset.js
================================================
'use strict';
describe('Controller: PasswordresetCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var PasswordresetCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
PasswordresetCtrl = $controller('PasswordresetCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/passwordresetconfirm.js
================================================
'use strict';
describe('Controller: PasswordresetconfirmCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var PasswordresetconfirmCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
PasswordresetconfirmCtrl = $controller('PasswordresetconfirmCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/register.js
================================================
'use strict';
describe('Controller: RegisterCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var RegisterCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
RegisterCtrl = $controller('RegisterCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/restricted.js
================================================
'use strict';
describe('Controller: RestrictedCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var RestrictedCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
RestrictedCtrl = $controller('RestrictedCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/userprofile.js
================================================
'use strict';
describe('Controller: UserprofileCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var UserprofileCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
UserprofileCtrl = $controller('UserprofileCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/controllers/verifyemail.js
================================================
'use strict';
describe('Controller: VerifyemailCtrl', function () {
// load the controller's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
var VerifyemailCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
VerifyemailCtrl = $controller('VerifyemailCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
================================================
FILE: test/spec/services/djangoAuth.js
================================================
'use strict';
describe('Service: Djangoauth', function () {
// load the service's module
beforeEach(module('angularDjangoRegistrationAuthApp'));
// instantiate service
var Djangoauth;
beforeEach(inject(function (_Djangoauth_) {
Djangoauth = _Djangoauth_;
}));
it('should do something', function () {
expect(!!Djangoauth).toBe(true);
});
});
gitextract_o9misfkw/
├── .bowerrc
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .jshintrc
├── .travis.yml
├── Gruntfile.js
├── README.md
├── app/
│ ├── .buildignore
│ ├── .htaccess
│ ├── 404.html
│ ├── index.html
│ ├── robots.txt
│ ├── scripts/
│ │ ├── app.js
│ │ ├── controllers/
│ │ │ ├── authrequired.js
│ │ │ ├── login.js
│ │ │ ├── logout.js
│ │ │ ├── main.js
│ │ │ ├── master.js
│ │ │ ├── passwordchange.js
│ │ │ ├── passwordreset.js
│ │ │ ├── passwordresetconfirm.js
│ │ │ ├── register.js
│ │ │ ├── restricted.js
│ │ │ ├── userprofile.js
│ │ │ └── verifyemail.js
│ │ └── services/
│ │ ├── djangoAuth.js
│ │ └── validate.js
│ ├── styles/
│ │ └── main.css
│ └── views/
│ ├── authrequired.html
│ ├── login.html
│ ├── logout.html
│ ├── main.html
│ ├── passwordchange.html
│ ├── passwordreset.html
│ ├── passwordresetconfirm.html
│ ├── register.html
│ ├── restricted.html
│ ├── userprofile.html
│ └── verifyemail.html
├── bower.json
├── karma-e2e.conf.js
├── karma.conf.js
├── package.json
└── test/
├── .jshintrc
├── runner.html
└── spec/
├── controllers/
│ ├── authrequired.js
│ ├── login.js
│ ├── logout.js
│ ├── main.js
│ ├── master.js
│ ├── passwordchange.js
│ ├── passwordreset.js
│ ├── passwordresetconfirm.js
│ ├── register.js
│ ├── restricted.js
│ ├── userprofile.js
│ └── verifyemail.js
└── services/
└── djangoAuth.js
Condensed preview — 59 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (98K chars).
[
{
"path": ".bowerrc",
"chars": 44,
"preview": "{\n \"directory\": \"app/bower_components\"\n}\n"
},
{
"path": ".editorconfig",
"chars": 415,
"preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
},
{
"path": ".gitattributes",
"chars": 11,
"preview": "* text=auto"
},
{
"path": ".gitignore",
"chars": 56,
"preview": "node_modules\ndist\n.tmp\n.sass-cache\napp/bower_components\n"
},
{
"path": ".jshintrc",
"chars": 394,
"preview": "{\n \"node\": true,\n \"browser\": true,\n \"esnext\": true,\n \"bitwise\": true,\n \"camelcase\": true,\n \"curly\": true,\n \"eqeqe"
},
{
"path": ".travis.yml",
"chars": 120,
"preview": "language: node_js\nnode_js:\n - '0.8'\n - '0.10'\nbefore_script:\n - 'npm install -g bower grunt-cli'\n - 'bower install'\n"
},
{
"path": "Gruntfile.js",
"chars": 8635,
"preview": "// Generated on 2014-04-21 using generator-angular 0.7.1\n'use strict';\n\n// # Globbing\n// for performance reasons we're o"
},
{
"path": "README.md",
"chars": 2325,
"preview": "AngularJS Module for [Django REST Auth](https://github.com/Tivix/django-rest-auth)\n====================================="
},
{
"path": "app/.buildignore",
"chars": 8,
"preview": "*.coffee"
},
{
"path": "app/.htaccess",
"chars": 24135,
"preview": "# Apache Configuration File\n\n# (!) Using `.htaccess` files slows down Apache, therefore, if you have access\n# to the mai"
},
{
"path": "app/404.html",
"chars": 3529,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <title>Page Not Found :(</title>\n <style>\n "
},
{
"path": "app/index.html",
"chars": 3959,
"preview": "<!doctype html>\n<!--[if lt IE 7]> <html class=\"no-js lt-ie9 lt-ie8 lt-ie7\"> <![endif]-->\n<!--[if IE 7]> <ht"
},
{
"path": "app/robots.txt",
"chars": 31,
"preview": "# robotstxt.org\n\nUser-agent: *\n"
},
{
"path": "app/scripts/app.js",
"chars": 3192,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp', [\n 'ngCookies',\n 'ngResource',\n 'ngSanitize',\n 'ng"
},
{
"path": "app/scripts/controllers/authrequired.js",
"chars": 411,
"preview": "'use strict';\n\n/**\n * @ngdoc function\n * @name angularDjangoRegistrationAuthApp.controller:AuthrequiredCtrl\n * @descript"
},
{
"path": "app/scripts/controllers/login.js",
"chars": 643,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('LoginCtrl', function ($scope, $location"
},
{
"path": "app/scripts/controllers/logout.js",
"chars": 168,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('LogoutCtrl', function ($scope, $locatio"
},
{
"path": "app/scripts/controllers/main.js",
"chars": 2239,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('MainCtrl', function ($scope, $cookies, "
},
{
"path": "app/scripts/controllers/master.js",
"chars": 1003,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('MasterCtrl', function ($scope, $locatio"
},
{
"path": "app/scripts/controllers/passwordchange.js",
"chars": 682,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('PasswordchangeCtrl', function ($scope, "
},
{
"path": "app/scripts/controllers/passwordreset.js",
"chars": 616,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('PasswordresetCtrl', function ($scope, d"
},
{
"path": "app/scripts/controllers/passwordresetconfirm.js",
"chars": 762,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('PasswordresetconfirmCtrl', function ($s"
},
{
"path": "app/scripts/controllers/register.js",
"chars": 696,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('RegisterCtrl', function ($scope, django"
},
{
"path": "app/scripts/controllers/restricted.js",
"chars": 407,
"preview": "'use strict';\n\n/**\n * @ngdoc function\n * @name angularDjangoRegistrationAuthApp.controller:RestrictedCtrl\n * @descriptio"
},
{
"path": "app/scripts/controllers/userprofile.js",
"chars": 715,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('UserprofileCtrl', function ($scope, dja"
},
{
"path": "app/scripts/controllers/verifyemail.js",
"chars": 321,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .controller('VerifyemailCtrl', function ($scope, $ro"
},
{
"path": "app/scripts/services/djangoAuth.js",
"chars": 7928,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .service('djangoAuth', function djangoAuth($q, $http"
},
{
"path": "app/scripts/services/validate.js",
"chars": 1816,
"preview": "'use strict';\n\nangular.module('angularDjangoRegistrationAuthApp')\n .service('Validate', function Validate() {\n retur"
},
{
"path": "app/styles/main.css",
"chars": 1411,
"preview": "/* Space out content a bit */\nbody {\n padding-top: 20px;\n padding-bottom: 20px;\n}\n\n/* Everything but the jumbotron get"
},
{
"path": "app/views/authrequired.html",
"chars": 73,
"preview": "<p>This is a restricted view. You must be authenticated to view it.</p>\n"
},
{
"path": "app/views/login.html",
"chars": 1009,
"preview": "<div id=\"login_view\" ng-controller=\"LoginCtrl\">\n <form role=\"form\" ng-submit=\"login(loginForm)\" name=\"loginForm\" novali"
},
{
"path": "app/views/logout.html",
"chars": 114,
"preview": "<div id=\"logout_view\" ng-controller=\"LogoutCtrl\">\n\t<div class=\"alert alert-info\">You have logged out.</div>\n</div>"
},
{
"path": "app/views/main.html",
"chars": 2227,
"preview": "<h4>Routes</h4>\n <p>\n <a ng-hide=\"authenticated\" href=\"#/login\" class=\"btn btn-primary\">Login</a>\n <a n"
},
{
"path": "app/views/passwordchange.html",
"chars": 1401,
"preview": "<div id=\"passwordChange_view\" ng-controller=\"PasswordchangeCtrl\">\n <div ng-if=\"complete == false\">\n <form role"
},
{
"path": "app/views/passwordreset.html",
"chars": 1008,
"preview": "<div id=\"passwordReset_view\" ng-controller=\"PasswordresetCtrl\">\n <div ng-if=\"complete == false\">\n <form role=\""
},
{
"path": "app/views/passwordresetconfirm.html",
"chars": 1388,
"preview": "<div id=\"passwordResetConfirm_view\" ng-controller=\"PasswordresetconfirmCtrl\">\n <div ng-if=\"complete == false\">\n "
},
{
"path": "app/views/register.html",
"chars": 2105,
"preview": "<div id=\"register_view\" ng-controller=\"RegisterCtrl\">\n <div ng-if=\"complete == false\">\n <form role=\"form\" ng-i"
},
{
"path": "app/views/restricted.html",
"chars": 125,
"preview": "<p>You have attempted to access a restricted page. Please login to continue.</p>\n<div ng-include=\"'views/login.html'\"><"
},
{
"path": "app/views/userprofile.html",
"chars": 1674,
"preview": "<div id=\"userProfile_view\" ng-controller=\"UserprofileCtrl\">\n <div ng-if=\"complete == false\">\n <form role=\"form"
},
{
"path": "app/views/verifyemail.html",
"chars": 260,
"preview": "<div id=\"verifyEmail_view\" ng-controller=\"VerifyemailCtrl\">\n\t<div ng-if=\"success\" class=\"alert alert-success\">You have s"
},
{
"path": "bower.json",
"chars": 445,
"preview": "{\n \"name\": \"angular-django-registration-auth\",\n \"version\": \"0.0.0\",\n \"dependencies\": {\n \"angular\": \"1.2.16\",\n \""
},
{
"path": "karma-e2e.conf.js",
"chars": 1348,
"preview": "// Karma configuration\n// http://karma-runner.github.io/0.10/config/configuration-file.html\n\nmodule.exports = function(c"
},
{
"path": "karma.conf.js",
"chars": 1564,
"preview": "// Karma configuration\n// http://karma-runner.github.io/0.10/config/configuration-file.html\n\nmodule.exports = function(c"
},
{
"path": "package.json",
"chars": 1071,
"preview": "{\n \"name\": \"angulardjangoregistrationauth\",\n \"version\": \"0.0.0\",\n \"dependencies\": {},\n \"devDependencies\": {\n \"gru"
},
{
"path": "test/.jshintrc",
"chars": 631,
"preview": "{\n \"node\": true,\n \"browser\": true,\n \"esnext\": true,\n \"bitwise\": true,\n \"camelcase\": true,\n \"curly\": true,\n \"eqeqe"
},
{
"path": "test/runner.html",
"chars": 225,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <title>End2end Test Runner</title>\n <script src=\"vendor/angular-scenari"
},
{
"path": "test/spec/controllers/authrequired.js",
"chars": 560,
"preview": "'use strict';\n\ndescribe('Controller: AuthrequiredCtrl', function () {\n\n // load the controller's module\n beforeEach(mo"
},
{
"path": "test/spec/controllers/login.js",
"chars": 532,
"preview": "'use strict';\n\ndescribe('Controller: LoginCtrl', function () {\n\n // load the controller's module\n beforeEach(module('a"
},
{
"path": "test/spec/controllers/logout.js",
"chars": 536,
"preview": "'use strict';\n\ndescribe('Controller: LogoutCtrl', function () {\n\n // load the controller's module\n beforeEach(module('"
},
{
"path": "test/spec/controllers/main.js",
"chars": 528,
"preview": "'use strict';\n\ndescribe('Controller: MainCtrl', function () {\n\n // load the controller's module\n beforeEach(module('an"
},
{
"path": "test/spec/controllers/master.js",
"chars": 536,
"preview": "'use strict';\n\ndescribe('Controller: MasterCtrl', function () {\n\n // load the controller's module\n beforeEach(module('"
},
{
"path": "test/spec/controllers/passwordchange.js",
"chars": 568,
"preview": "'use strict';\n\ndescribe('Controller: PasswordchangeCtrl', function () {\n\n // load the controller's module\n beforeEach("
},
{
"path": "test/spec/controllers/passwordreset.js",
"chars": 564,
"preview": "'use strict';\n\ndescribe('Controller: PasswordresetCtrl', function () {\n\n // load the controller's module\n beforeEach(m"
},
{
"path": "test/spec/controllers/passwordresetconfirm.js",
"chars": 592,
"preview": "'use strict';\n\ndescribe('Controller: PasswordresetconfirmCtrl', function () {\n\n // load the controller's module\n befor"
},
{
"path": "test/spec/controllers/register.js",
"chars": 544,
"preview": "'use strict';\n\ndescribe('Controller: RegisterCtrl', function () {\n\n // load the controller's module\n beforeEach(module"
},
{
"path": "test/spec/controllers/restricted.js",
"chars": 552,
"preview": "'use strict';\n\ndescribe('Controller: RestrictedCtrl', function () {\n\n // load the controller's module\n beforeEach(modu"
},
{
"path": "test/spec/controllers/userprofile.js",
"chars": 556,
"preview": "'use strict';\n\ndescribe('Controller: UserprofileCtrl', function () {\n\n // load the controller's module\n beforeEach(mod"
},
{
"path": "test/spec/controllers/verifyemail.js",
"chars": 556,
"preview": "'use strict';\n\ndescribe('Controller: VerifyemailCtrl', function () {\n\n // load the controller's module\n beforeEach(mod"
},
{
"path": "test/spec/services/djangoAuth.js",
"chars": 370,
"preview": "'use strict';\n\ndescribe('Service: Djangoauth', function () {\n\n // load the service's module\n beforeEach(module('angula"
}
]
About this extraction
This page contains the full source code of the Tivix/angular-django-registration-auth GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 59 files (88.2 KB), approximately 21.9k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.