First attempt at getting a prototype up

This commit is contained in:
Kyle Corbelli 2017-09-02 15:07:05 -07:00
parent d0e63d5b9c
commit 10488ed6ba
40 changed files with 4673 additions and 88 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

View File

@ -1,56 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
exports.__esModule = true;
var types_1 = require("./types");
var configureActions = function (authUrl) {
var doThing = function () { return ({
type: types_1.DO_THING
}); };
var doThunkThing = function () { return function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
new Promise(function (resolve) { return resolve(); });
return [2 /*return*/];
});
});
}; };
return {
doThing: doThing,
doThunkThing: doThunkThing
};
};
exports["default"] = configureActions;

View File

@ -1,21 +0,0 @@
import {
DO_THING,
DoThingAction,
} from './types'
const configureActions = (authUrl: string) => {
const doThing = (): DoThingAction => ({
type: DO_THING,
})
const doThunkThing = () => async function (): Promise<void> {
new Promise((resolve) => resolve())
}
return {
doThing,
doThunkThing,
}
}
export default configureActions

243
dist/actions.js vendored Normal file
View File

@ -0,0 +1,243 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var axios_1 = require("axios");
var types_1 = require("./types");
var auth_1 = require("./services/auth"); // <- maybe this is where you pass in the platform paramter, specifying if it is for a browser or for React Native
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Pure Redux actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
exports.registrationRequestSent = function () { return ({
type: types_1.REGISTRATION_REQUEST_SENT,
}); };
exports.registrationRequestSucceeded = function (userAttributes) { return ({
type: types_1.REGISTRATION_REQUEST_SUCCEEDED,
payload: {
userAttributes: userAttributes,
},
}); };
exports.registrationRequestFailed = function () { return ({
type: types_1.REGISTRATION_REQUEST_FAILED,
}); };
exports.verifyTokenRequestSent = function () { return ({
type: types_1.VERIFY_TOKEN_REQUEST_SENT,
}); };
exports.verifyTokenRequestSucceeded = function (userAttributes) { return ({
type: types_1.VERIFY_TOKEN_REQUEST_SUCCEEDED,
payload: {
userAttributes: userAttributes,
},
}); };
exports.verifyTokenRequestFailed = function () { return ({
type: types_1.VERIFY_TOKEN_REQUEST_FAILED,
}); };
exports.signInRequestSent = function () { return ({
type: types_1.SIGNIN_REQUEST_SENT,
}); };
exports.signInRequestSucceeded = function (userAttributes) { return ({
type: types_1.SIGNIN_REQUEST_SUCCEEDED,
payload: {
userAttributes: userAttributes,
},
}); };
exports.signInRequestFailed = function () { return ({
type: types_1.SIGNIN_REQUEST_FAILED,
}); };
exports.signOutRequestSent = function () { return ({
type: types_1.SIGNOUT_REQUEST_SENT,
}); };
exports.signOutRequestSucceeded = function () { return ({
type: types_1.SIGNOUT_REQUEST_SUCCEEDED,
}); };
exports.signOutRequestFailed = function () { return ({
type: types_1.SIGNOUT_REQUEST_FAILED,
}); };
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Async Redux Thunk actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Maybe type this even:
var theActionsExportThatShouldBeRenamed = function (authUrl) {
var registerUser = function (userRegistrationDetails) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var firstName, email, password, passwordConfirmation, response, userAttributes, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.registrationRequestSent());
firstName = userRegistrationDetails.firstName, email = userRegistrationDetails.email, password = userRegistrationDetails.password, passwordConfirmation = userRegistrationDetails.passwordConfirmation;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default({
method: 'POST',
url: authUrl,
data: {
email: email,
name: firstName,
password: password,
password_confirmation: passwordConfirmation,
},
})];
case 2:
response = _a.sent();
auth_1.setAuthHeaders(response.headers);
auth_1.persistAuthHeadersInLocalStorage(response.headers);
userAttributes = {
firstName: firstName,
};
dispatch(exports.registrationRequestSucceeded(userAttributes));
return [3 /*break*/, 4];
case 3:
error_1 = _a.sent();
dispatch(exports.registrationRequestFailed());
throw error_1;
case 4: return [2 /*return*/];
}
});
});
}; };
var verifyToken = function (verificationParams) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var response, name_1, userAttributes, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.verifyTokenRequestSent());
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default({
method: 'GET',
url: authUrl + "/validate_token",
params: verificationParams,
})];
case 2:
response = _a.sent();
name_1 = response.data.data.name;
auth_1.setAuthHeaders(response.headers);
auth_1.persistAuthHeadersInLocalStorage(response.headers);
userAttributes = {
firstName: name_1,
};
dispatch(exports.verifyTokenRequestSucceeded(userAttributes));
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
dispatch(exports.verifyTokenRequestFailed());
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
}; };
var signInUser = function (userSignInCredentials) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var email, password, response, name_2, userAttributes, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.signInRequestSent());
email = userSignInCredentials.email, password = userSignInCredentials.password;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default({
method: 'POST',
url: authUrl + "/sign_in",
data: {
email: email,
password: password,
},
})];
case 2:
response = _a.sent();
auth_1.setAuthHeaders(response.headers);
auth_1.persistAuthHeadersInLocalStorage(response.headers);
name_2 = response.data.data.name;
userAttributes = {
firstName: name_2,
};
dispatch(exports.signInRequestSucceeded(userAttributes));
return [3 /*break*/, 4];
case 3:
error_3 = _a.sent();
dispatch(exports.signInRequestFailed());
throw error_3;
case 4: return [2 /*return*/];
}
});
});
}; };
var signOutUser = function (userSignOutCredentials) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.signOutRequestSent());
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default({
method: 'DELETE',
url: authUrl + "/sign_out",
data: userSignOutCredentials,
})];
case 2:
_a.sent();
auth_1.deleteAuthHeaders();
auth_1.deleteAuthHeadersFromLocalStorage();
dispatch(exports.signOutRequestSucceeded());
return [3 /*break*/, 4];
case 3:
error_4 = _a.sent();
dispatch(exports.signOutRequestFailed());
throw error_4;
case 4: return [2 /*return*/];
}
});
});
}; };
return {
registerUser: registerUser,
verifyToken: verifyToken,
signInUser: signInUser,
signOutUser: signOutUser,
};
};
exports.default = theActionsExportThatShouldBeRenamed;
//# sourceMappingURL=actions.js.map

1
dist/actions.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}

25
dist/index.js vendored Normal file
View File

@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var actions_1 = require("./actions");
exports.theActionsExportThatShouldBeRenamed = actions_1.default;
var reducers_1 = require("./reducers");
exports.reduxTokenAuthReducer = reducers_1.default;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Example of how the end-user will import the actions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// import {
// generateAuthFunctions,
// } from 'redux-token-auth'
//
// const authUrl: string = 'http://www.someapp.com/auth'
// const userAttributes = {
// firstName: 'name',
// imageUrl: 'image_url',
// }
// const {
// registerUser,
// verifyToken,
// signInUser,
// signOutUser,
// } = generateAuthFunctions(authUrl, userAttributes)
//# sourceMappingURL=index.js.map

1
dist/index.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qCAA2D;AAIzD,8CAJK,iBAAmC,CAIL;AAHrC,uCAA8C;AAI5C,gCAJK,kBAAqB,CAIL;AAGvB,wHAAwH;AACxH,sDAAsD;AACtD,wHAAwH;AAExH,WAAW;AACX,2BAA2B;AAC3B,4BAA4B;AAC5B,EAAE;AACF,wDAAwD;AACxD,2BAA2B;AAC3B,uBAAuB;AACvB,2BAA2B;AAC3B,IAAI;AACJ,UAAU;AACV,kBAAkB;AAClB,iBAAiB;AACjB,gBAAgB;AAChB,iBAAiB;AACjB,qDAAqD"}

11
dist/initial-state.js vendored Normal file
View File

@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var initialState = {
currentUser: {
isLoggedIn: false,
isLoading: false,
attributes: {},
},
};
exports.default = initialState;
//# sourceMappingURL=initial-state.js.map

1
dist/initial-state.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"initial-state.js","sourceRoot":"","sources":["../src/initial-state.ts"],"names":[],"mappings":";;AAIA,IAAM,YAAY,GAAe;IAC/B,WAAW,EAAE;QACX,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,EAAE;KACf;CACF,CAAA;AAED,kBAAe,YAAY,CAAA"}

40
dist/reducers/current-user/index.js vendored Normal file
View File

@ -0,0 +1,40 @@
"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var types_1 = require("../../types");
var initial_state_1 = require("../../initial-state");
var initialUser = initial_state_1.default.currentUser;
var currentUser = function (state, action) {
if (state === void 0) { state = initialUser; }
switch (action.type) {
case types_1.REGISTRATION_REQUEST_SENT:
case types_1.VERIFY_TOKEN_REQUEST_SENT:
case types_1.SIGNIN_REQUEST_SENT:
case types_1.SIGNOUT_REQUEST_SENT:
return __assign({}, state, { isLoading: true });
case types_1.REGISTRATION_REQUEST_SUCCEEDED:
case types_1.VERIFY_TOKEN_REQUEST_SUCCEEDED:
case types_1.SIGNIN_REQUEST_SUCCEEDED:
var userAttributes = action.payload.userAttributes;
return __assign({}, state, { attributes: __assign({}, userAttributes), isLoading: false, isLoggedIn: true });
case types_1.REGISTRATION_REQUEST_FAILED:
case types_1.VERIFY_TOKEN_REQUEST_FAILED:
case types_1.SIGNIN_REQUEST_FAILED:
return __assign({}, state, { isLoading: false, isLoggedIn: false });
case types_1.SIGNOUT_REQUEST_SUCCEEDED:
return __assign({}, state, { attributes: __assign({}, state.attributes, { firstName: null }), isLoading: false, isLoggedIn: false });
case types_1.SIGNOUT_REQUEST_FAILED:
return __assign({}, state, { isLoading: false });
default:
return state;
}
};
exports.default = currentUser;
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/reducers/current-user/index.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qCAeoB;AACpB,qDAA8C;AAG5C,IAAA,iDAAwB,CACV;AAEhB,IAAM,WAAW,GAAG,UAAC,KAAyB,EAAE,MAAmB;IAA9C,sBAAA,EAAA,mBAAyB;IAC5C,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACpB,KAAK,iCAAyB,CAAC;QAC/B,KAAK,iCAAyB,CAAC;QAC/B,KAAK,2BAAmB,CAAC;QACzB,KAAK,4BAAoB;YACvB,MAAM,cACD,KAAK,IACR,SAAS,EAAE,IAAI,IAChB;QACH,KAAK,sCAA8B,CAAC;QACpC,KAAK,sCAA8B,CAAC;QACpC,KAAK,gCAAwB;YACnB,IAAA,8CAAc,CAAmB;YACzC,MAAM,cACD,KAAK,IACR,UAAU,eAAO,cAAc,GAC/B,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,IAAI,IACjB;QACH,KAAK,mCAA2B,CAAC;QACjC,KAAK,mCAA2B,CAAC;QACjC,KAAK,6BAAqB;YACxB,MAAM,cACD,KAAK,IACR,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,KAAK,IAClB;QACH,KAAK,iCAAyB;YAC5B,MAAM,cACD,KAAK,IACR,UAAU,eACL,KAAK,CAAC,UAAU,IACnB,SAAS,EAAE,IAAI,KAEjB,SAAS,EAAE,KAAK,EAChB,UAAU,EAAE,KAAK,IAClB;QACH,KAAK,8BAAsB;YACzB,MAAM,cACD,KAAK,IACR,SAAS,EAAE,KAAK,IACjB;QACH;YACE,MAAM,CAAC,KAAK,CAAA;IAChB,CAAC;AACH,CAAC,CAAA;AAED,kBAAe,WAAW,CAAA"}

21
dist/reducers/index.js vendored Normal file
View File

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var redux_1 = require("redux");
var current_user_1 = require("./current-user");
var reduxTokenAuthReducer = redux_1.combineReducers({
currentUser: current_user_1.default,
});
exports.default = reduxTokenAuthReducer;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// An example of how the end-user will integrate this into their Redux store
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// import { combineReducers } from 'redux'
// import { reduxTokenAuthReducer } from 'redux-token-auth'
// import { myCustomReducer } from './my-custom-reducer'
//
// const rootReducer = combineReducers({
// reduxTokenAuth: reduxTokenAuthReducer,
// myCustomReducer,
// })
// Remember, they will have to user Redux Thunk when configuring their store
//# sourceMappingURL=index.js.map

1
dist/reducers/index.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reducers/index.ts"],"names":[],"mappings":";;AAAA,+BAAuC;AACvC,+CAAwC;AAExC,IAAM,qBAAqB,GAAG,uBAAe,CAAC;IAC5C,WAAW,wBAAA;CACZ,CAAC,CAAA;AAEF,kBAAe,qBAAqB,CAAA;AAEpC,wHAAwH;AACxH,4EAA4E;AAC5E,wHAAwH;AAExH,0CAA0C;AAC1C,2DAA2D;AAC3D,wDAAwD;AACxD,EAAE;AACF,wCAAwC;AACxC,2CAA2C;AAC3C,qBAAqB;AACrB,KAAK;AAEL,4EAA4E"}

33
dist/services/auth.js vendored Normal file
View File

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var axios_1 = require("axios");
var authHeaderKeys = [
'access-token',
'token-type',
'client',
'expiry',
'uid',
];
exports.setAuthHeaders = function (headers) {
authHeaderKeys.forEach(function (key) {
axios_1.default.defaults.headers.common[key] = headers[key];
});
};
// Will have to take a parameter from the package user to determine if this is for a browser or for React Native:
exports.persistAuthHeadersInLocalStorage = function (headers) {
authHeaderKeys.forEach(function (key) {
localStorage.setItem(key, headers[key]);
});
};
exports.deleteAuthHeaders = function () {
authHeaderKeys.forEach(function (key) {
delete axios_1.default.defaults.headers.common[key];
});
};
// Will have to take a parameter from the package user to determine if this is for a browser or for React Native:
exports.deleteAuthHeadersFromLocalStorage = function () {
authHeaderKeys.forEach(function (key) {
localStorage.removeItem(key);
});
};
//# sourceMappingURL=auth.js.map

1
dist/services/auth.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":";;AAAA,+BAAyB;AAGzB,IAAM,cAAc,GAAkB;IACpC,cAAc;IACd,YAAY;IACZ,QAAQ;IACR,QAAQ;IACR,KAAK;CACN,CAAA;AAEY,QAAA,cAAc,GAAG,UAAC,OAAoB;IACjD,cAAc,CAAC,OAAO,CAAC,UAAC,GAAW;QACjC,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,iHAAiH;AACpG,QAAA,gCAAgC,GAAG,UAAC,OAAoB;IACnE,cAAc,CAAC,OAAO,CAAC,UAAC,GAAW;QACjC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAEY,QAAA,iBAAiB,GAAG;IAC/B,cAAc,CAAC,OAAO,CAAC,UAAC,GAAW;QACjC,OAAO,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,iHAAiH;AACpG,QAAA,iCAAiC,GAAG;IAC/C,cAAc,CAAC,OAAO,CAAC,UAAC,GAAW;QACjC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}

16
dist/types.js vendored Normal file
View File

@ -0,0 +1,16 @@
"use strict";
// Maybe make this the index.ts of a types directory so you can split things up
Object.defineProperty(exports, "__esModule", { value: true });
exports.REGISTRATION_REQUEST_SENT = 'redux-token-auth/REGISTRATION_REQUEST_SENT';
exports.REGISTRATION_REQUEST_SUCCEEDED = 'redux-token-auth/REGISTRATION_REQUEST_SUCCEEDED';
exports.REGISTRATION_REQUEST_FAILED = 'redux-token-auth/REGISTRATION_REQUEST_FAILED';
exports.VERIFY_TOKEN_REQUEST_SENT = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SENT';
exports.VERIFY_TOKEN_REQUEST_SUCCEEDED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SUCCEEDED';
exports.VERIFY_TOKEN_REQUEST_FAILED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_FAILED';
exports.SIGNIN_REQUEST_SENT = 'redux-token-auth/SIGNIN_REQUEST_SENT';
exports.SIGNIN_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNIN_REQUEST_SUCCEEDED';
exports.SIGNIN_REQUEST_FAILED = 'redux-token-auth/SIGNIN_REQUEST_FAILED';
exports.SIGNOUT_REQUEST_SENT = 'redux-token-auth/SIGNOUT_REQUEST_SENT';
exports.SIGNOUT_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNOUT_REQUEST_SUCCEEDED';
exports.SIGNOUT_REQUEST_FAILED = 'redux-token-auth/SIGNOUT_REQUEST_FAILED';
//# sourceMappingURL=types.js.map

1
dist/types.js.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,+EAA+E;;AAkClE,QAAA,yBAAyB,GAA8B,4CAA4C,CAAA;AAGnG,QAAA,8BAA8B,GAAmC,iDAAiD,CAAA;AAGlH,QAAA,2BAA2B,GAAgC,8CAA8C,CAAA;AAGzG,QAAA,yBAAyB,GAA8B,4CAA4C,CAAA;AAGnG,QAAA,8BAA8B,GAAmC,iDAAiD,CAAA;AAGlH,QAAA,2BAA2B,GAAgC,8CAA8C,CAAA;AAGzG,QAAA,mBAAmB,GAAwB,sCAAsC,CAAA;AAGjF,QAAA,wBAAwB,GAA6B,2CAA2C,CAAA;AAGhG,QAAA,qBAAqB,GAA0B,wCAAwC,CAAA;AAGvF,QAAA,oBAAoB,GAAyB,uCAAuC,CAAA;AAGpF,QAAA,yBAAyB,GAA8B,4CAA4C,CAAA;AAGnG,QAAA,sBAAsB,GAA2B,yCAAyC,CAAA"}

View File

2969
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,14 +2,20 @@
"name": "redux-token-auth",
"version": "0.1.0",
"description": "Redux actions and reducers to integrate with Devise Token Auth",
"main": "index.js",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc"
},
"repository": {
"type": "git",
"url": "https://github.com/kylecorbelli/redux-token-auth.git"
},
"keywords": [
"react",
"redux",
"auth",
"authentication",
"token",
"devise",
"oauth"
@ -17,6 +23,13 @@
"author": "Kyle Corbelli",
"license": "MIT",
"devDependencies": {
"@types/jest": "^20.0.8",
"jest": "^20.0.4",
"typescript": "^2.5.2"
},
"dependencies": {
"@types/axios": "^0.14.0",
"axios": "^0.16.2",
"redux": "^3.7.2"
}
}

242
src/actions.js Normal file
View File

@ -0,0 +1,242 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
exports.__esModule = true;
var axios_1 = require("axios");
var types_1 = require("./types");
var auth_1 = require("./services/auth"); // <- maybe this is where you pass in the platform paramter, specifying if it is for a browser or for React Native
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Pure Redux actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
exports.registrationRequestSent = function () { return ({
type: types_1.REGISTRATION_REQUEST_SENT
}); };
exports.registrationRequestSucceeded = function (userAttributes) { return ({
type: types_1.REGISTRATION_REQUEST_SUCCEEDED,
payload: {
userAttributes: userAttributes
}
}); };
exports.registrationRequestFailed = function () { return ({
type: types_1.REGISTRATION_REQUEST_FAILED
}); };
exports.verifyTokenRequestSent = function () { return ({
type: types_1.VERIFY_TOKEN_REQUEST_SENT
}); };
exports.verifyTokenRequestSucceeded = function (userAttributes) { return ({
type: types_1.VERIFY_TOKEN_REQUEST_SUCCEEDED,
payload: {
userAttributes: userAttributes
}
}); };
exports.verifyTokenRequestFailed = function () { return ({
type: types_1.VERIFY_TOKEN_REQUEST_FAILED
}); };
exports.signInRequestSent = function () { return ({
type: types_1.SIGNIN_REQUEST_SENT
}); };
exports.signInRequestSucceeded = function (userAttributes) { return ({
type: types_1.SIGNIN_REQUEST_SUCCEEDED,
payload: {
userAttributes: userAttributes
}
}); };
exports.signInRequestFailed = function () { return ({
type: types_1.SIGNIN_REQUEST_FAILED
}); };
exports.signOutRequestSent = function () { return ({
type: types_1.SIGNOUT_REQUEST_SENT
}); };
exports.signOutRequestSucceeded = function () { return ({
type: types_1.SIGNOUT_REQUEST_SUCCEEDED
}); };
exports.signOutRequestFailed = function () { return ({
type: types_1.SIGNOUT_REQUEST_FAILED
}); };
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Async Redux Thunk actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Maybe type this even:
var theActionsExportThatShouldBeRenamed = function (authUrl) {
var registerUser = function (userRegistrationDetails) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var firstName, email, password, passwordConfirmation, response, userAttributes, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.registrationRequestSent());
firstName = userRegistrationDetails.firstName, email = userRegistrationDetails.email, password = userRegistrationDetails.password, passwordConfirmation = userRegistrationDetails.passwordConfirmation;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1["default"]({
method: 'POST',
url: authUrl,
data: {
email: email,
name: firstName,
password: password,
password_confirmation: passwordConfirmation
}
})];
case 2:
response = _a.sent();
auth_1.setAuthHeaders(response.headers);
auth_1.persistAuthHeadersInLocalStorage(response.headers);
userAttributes = {
firstName: firstName
};
dispatch(exports.registrationRequestSucceeded(userAttributes));
return [3 /*break*/, 4];
case 3:
error_1 = _a.sent();
dispatch(exports.registrationRequestFailed());
throw error_1;
case 4: return [2 /*return*/];
}
});
});
}; };
var verifyToken = function (verificationParams) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var response, name, userAttributes, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.verifyTokenRequestSent());
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1["default"]({
method: 'GET',
url: authUrl + "/validate_token",
params: verificationParams
})];
case 2:
response = _a.sent();
name = response.data.data.name;
auth_1.setAuthHeaders(response.headers);
auth_1.persistAuthHeadersInLocalStorage(response.headers);
userAttributes = {
firstName: name
};
dispatch(exports.verifyTokenRequestSucceeded(userAttributes));
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
dispatch(exports.verifyTokenRequestFailed());
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
}; };
var signInUser = function (userSignInCredentials) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var email, password, response, name, userAttributes, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.signInRequestSent());
email = userSignInCredentials.email, password = userSignInCredentials.password;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1["default"]({
method: 'POST',
url: authUrl + "/sign_in",
data: {
email: email,
password: password
}
})];
case 2:
response = _a.sent();
auth_1.setAuthHeaders(response.headers);
auth_1.persistAuthHeadersInLocalStorage(response.headers);
name = response.data.data.name;
userAttributes = {
firstName: name
};
dispatch(exports.signInRequestSucceeded(userAttributes));
return [3 /*break*/, 4];
case 3:
error_3 = _a.sent();
dispatch(exports.signInRequestFailed());
throw error_3;
case 4: return [2 /*return*/];
}
});
});
}; };
var signOutUser = function (userSignOutCredentials) { return function (dispatch) {
return __awaiter(this, void 0, void 0, function () {
var error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
dispatch(exports.signOutRequestSent());
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1["default"]({
method: 'DELETE',
url: authUrl + "/sign_out",
data: userSignOutCredentials
})];
case 2:
_a.sent();
auth_1.deleteAuthHeaders();
auth_1.deleteAuthHeadersFromLocalStorage();
dispatch(exports.signOutRequestSucceeded());
return [3 /*break*/, 4];
case 3:
error_4 = _a.sent();
dispatch(exports.signOutRequestFailed());
throw error_4;
case 4: return [2 /*return*/];
}
});
});
}; };
return {
registerUser: registerUser,
verifyToken: verifyToken,
signInUser: signInUser,
signOutUser: signOutUser
};
};
exports["default"] = theActionsExportThatShouldBeRenamed;

225
src/actions.ts Normal file
View File

@ -0,0 +1,225 @@
import axios from 'axios'
// import { authUrl } from '../../constants' // this has to be passed in by the package user
import { Dispatch } from 'redux'
import {
AuthResponse,
VerificationParams,
UserAttributes,
UserRegistrationDetails,
UserSignInCredentials,
UserSignOutCredentials,
REGISTRATION_REQUEST_SENT,
REGISTRATION_REQUEST_SUCCEEDED,
REGISTRATION_REQUEST_FAILED,
VERIFY_TOKEN_REQUEST_SENT,
VERIFY_TOKEN_REQUEST_SUCCEEDED,
VERIFY_TOKEN_REQUEST_FAILED,
SIGNIN_REQUEST_SENT,
SIGNIN_REQUEST_SUCCEEDED,
SIGNIN_REQUEST_FAILED,
SIGNOUT_REQUEST_SENT,
SIGNOUT_REQUEST_SUCCEEDED,
SIGNOUT_REQUEST_FAILED,
RegistrationRequestSentAction,
RegistrationRequestSucceededAction,
RegistrationRequestFailedAction,
VerifyTokenRequestSentAction,
VerifyTokenRequestSucceededAction,
VerifyTokenRequestFailedAction,
SignInRequestSentAction,
SignInRequestSucceededAction,
SignInRequestFailedAction,
SignOutRequestSentAction,
SignOutRequestSucceededAction,
SignOutRequestFailedAction,
} from './types'
import {
setAuthHeaders,
deleteAuthHeaders,
persistAuthHeadersInLocalStorage,
deleteAuthHeadersFromLocalStorage,
} from './services/auth' // <- maybe this is where you pass in the platform paramter, specifying if it is for a browser or for React Native
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Pure Redux actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
export const registrationRequestSent = (): RegistrationRequestSentAction => ({
type: REGISTRATION_REQUEST_SENT,
})
export const registrationRequestSucceeded = (userAttributes: UserAttributes): RegistrationRequestSucceededAction => ({
type: REGISTRATION_REQUEST_SUCCEEDED,
payload: {
userAttributes,
},
})
export const registrationRequestFailed = (): RegistrationRequestFailedAction => ({
type: REGISTRATION_REQUEST_FAILED,
})
export const verifyTokenRequestSent = (): VerifyTokenRequestSentAction => ({
type: VERIFY_TOKEN_REQUEST_SENT,
})
export const verifyTokenRequestSucceeded = (userAttributes: UserAttributes): VerifyTokenRequestSucceededAction => ({
type: VERIFY_TOKEN_REQUEST_SUCCEEDED,
payload: {
userAttributes,
},
})
export const verifyTokenRequestFailed = (): VerifyTokenRequestFailedAction => ({
type: VERIFY_TOKEN_REQUEST_FAILED,
})
export const signInRequestSent = (): SignInRequestSentAction => ({
type: SIGNIN_REQUEST_SENT,
})
export const signInRequestSucceeded = (userAttributes: UserAttributes): SignInRequestSucceededAction => ({
type: SIGNIN_REQUEST_SUCCEEDED,
payload: {
userAttributes,
},
})
export const signInRequestFailed = (): SignInRequestFailedAction => ({
type: SIGNIN_REQUEST_FAILED,
})
export const signOutRequestSent = (): SignOutRequestSentAction => ({
type: SIGNOUT_REQUEST_SENT,
})
export const signOutRequestSucceeded = (): SignOutRequestSucceededAction => ({
type: SIGNOUT_REQUEST_SUCCEEDED,
})
export const signOutRequestFailed = (): SignOutRequestFailedAction => ({
type: SIGNOUT_REQUEST_FAILED,
})
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Async Redux Thunk actions:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Maybe type this even:
const theActionsExportThatShouldBeRenamed = (authUrl: string) => {
const registerUser = (
userRegistrationDetails: UserRegistrationDetails,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(registrationRequestSent())
const {
firstName,
email,
password,
passwordConfirmation,
} = userRegistrationDetails
try {
const response: AuthResponse = await axios({
method: 'POST',
url: authUrl,
data: {
email,
name: firstName, // even this is tricky because it requires the user's devise configuration to allow the "name" attribute
password,
password_confirmation: passwordConfirmation,
},
})
setAuthHeaders(response.headers)
persistAuthHeadersInLocalStorage(response.headers)
// Gonna need to refer to the passed-in User model configuration from the package user
const userAttributes: UserAttributes = {
firstName,
}
dispatch(registrationRequestSucceeded(userAttributes))
} catch (error) {
dispatch(registrationRequestFailed())
throw error
}
}
const verifyToken = (
verificationParams: VerificationParams,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(verifyTokenRequestSent())
try {
const response = await axios({
method: 'GET',
url: `${authUrl}/validate_token`,
params: verificationParams,
})
const { name } = response.data.data
setAuthHeaders(response.headers)
persistAuthHeadersInLocalStorage(response.headers)
// Gonna need to refer to the passed-in User model configuration from the package user
const userAttributes: UserAttributes = {
firstName: name,
}
dispatch(verifyTokenRequestSucceeded(userAttributes))
} catch (error) {
dispatch(verifyTokenRequestFailed())
}
}
const signInUser = (
userSignInCredentials: UserSignInCredentials,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(signInRequestSent())
const {
email,
password,
} = userSignInCredentials
try {
const response = await axios({
method: 'POST',
url: `${authUrl}/sign_in`,
data: {
email,
password,
},
})
setAuthHeaders(response.headers)
persistAuthHeadersInLocalStorage(response.headers)
// Gonna need to refer to the passed-in User model configuration from the package user
const { name } = response.data.data
const userAttributes: UserAttributes = {
firstName: name,
}
dispatch(signInRequestSucceeded(userAttributes))
} catch (error) {
dispatch(signInRequestFailed())
throw error
}
}
const signOutUser = (
userSignOutCredentials: UserSignOutCredentials,
) => async function (dispatch: Dispatch<{}>): Promise<void> {
dispatch(signOutRequestSent())
try {
await axios({
method: 'DELETE',
url: `${authUrl}/sign_out`,
data: userSignOutCredentials,
})
deleteAuthHeaders()
deleteAuthHeadersFromLocalStorage()
dispatch(signOutRequestSucceeded())
} catch (error) {
dispatch(signOutRequestFailed())
throw error
}
}
return {
registerUser,
verifyToken,
signInUser,
signOutUser,
}
}
export default theActionsExportThatShouldBeRenamed

24
src/index.js Normal file
View File

@ -0,0 +1,24 @@
"use strict";
exports.__esModule = true;
var actions_1 = require("./actions");
exports.theActionsExportThatShouldBeRenamed = actions_1["default"];
var reducers_1 = require("./reducers");
exports.reduxTokenAuthReducer = reducers_1["default"];
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Example of how the end-user will import the actions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// import {
// generateAuthFunctions,
// } from 'redux-token-auth'
//
// const authUrl: string = 'http://www.someapp.com/auth'
// const userAttributes = {
// firstName: 'name',
// imageUrl: 'image_url',
// }
// const {
// registerUser,
// verifyToken,
// signInUser,
// signOutUser,
// } = generateAuthFunctions(authUrl, userAttributes)

27
src/index.ts Normal file
View File

@ -0,0 +1,27 @@
import theActionsExportThatShouldBeRenamed from './actions'
import reduxTokenAuthReducer from './reducers'
export {
theActionsExportThatShouldBeRenamed,
reduxTokenAuthReducer,
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Example of how the end-user will import the actions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// import {
// generateAuthFunctions,
// } from 'redux-token-auth'
//
// const authUrl: string = 'http://www.someapp.com/auth'
// const userAttributes = {
// firstName: 'name',
// imageUrl: 'image_url',
// }
// const {
// registerUser,
// verifyToken,
// signInUser,
// signOutUser,
// } = generateAuthFunctions(authUrl, userAttributes)

10
src/initial-state.js Normal file
View File

@ -0,0 +1,10 @@
"use strict";
exports.__esModule = true;
var initialState = {
currentUser: {
isLoggedIn: false,
isLoading: false,
attributes: {}
}
};
exports["default"] = initialState;

13
src/initial-state.ts Normal file
View File

@ -0,0 +1,13 @@
import {
ReduxState
} from './types'
const initialState: ReduxState = {
currentUser: {
isLoggedIn: false,
isLoading: false,
attributes: {},
},
}
export default initialState

View File

@ -0,0 +1,39 @@
"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
exports.__esModule = true;
var types_1 = require("../../types");
var initial_state_1 = require("../../initial-state");
var initialUser = initial_state_1["default"].currentUser;
var currentUser = function (state, action) {
if (state === void 0) { state = initialUser; }
switch (action.type) {
case types_1.REGISTRATION_REQUEST_SENT:
case types_1.VERIFY_TOKEN_REQUEST_SENT:
case types_1.SIGNIN_REQUEST_SENT:
case types_1.SIGNOUT_REQUEST_SENT:
return __assign({}, state, { isLoading: true });
case types_1.REGISTRATION_REQUEST_SUCCEEDED:
case types_1.VERIFY_TOKEN_REQUEST_SUCCEEDED:
case types_1.SIGNIN_REQUEST_SUCCEEDED:
var userAttributes = action.payload.userAttributes;
return __assign({}, state, { attributes: __assign({}, userAttributes), isLoading: false, isLoggedIn: true });
case types_1.REGISTRATION_REQUEST_FAILED:
case types_1.VERIFY_TOKEN_REQUEST_FAILED:
case types_1.SIGNIN_REQUEST_FAILED:
return __assign({}, state, { isLoading: false, isLoggedIn: false });
case types_1.SIGNOUT_REQUEST_SUCCEEDED:
return __assign({}, state, { attributes: __assign({}, state.attributes, { firstName: null }), isLoading: false, isLoggedIn: false });
case types_1.SIGNOUT_REQUEST_FAILED:
return __assign({}, state, { isLoading: false });
default:
return state;
}
};
exports["default"] = currentUser;

View File

@ -0,0 +1,191 @@
import currentUser from './index'
import {
RegistrationRequestSentAction,
RegistrationRequestSucceededAction,
RegistrationRequestFailedAction,
VerifyTokenRequestSentAction,
VerifyTokenRequestSucceededAction,
VerifyTokenRequestFailedAction,
SignInRequestSentAction,
SignInRequestSucceededAction,
SignInRequestFailedAction,
SignOutRequestSentAction,
SignOutRequestSucceededAction,
SignOutRequestFailedAction,
User,
UserAttributes,
} from '../../types'
import {
registrationRequestSent,
registrationRequestSucceeded,
registrationRequestFailed,
verifyTokenRequestSent,
verifyTokenRequestSucceeded,
verifyTokenRequestFailed,
signInRequestSent,
signInRequestSucceeded,
signInRequestFailed,
signOutRequestSent,
signOutRequestSucceeded,
signOutRequestFailed,
} from '../../actions'
describe('currentUser', () => {
const alreadyLoadingState: User = {
attributes: {
firstName: null,
},
isLoading: true,
isLoggedIn: false,
}
const loggedInUser: User = {
attributes: {
firstName: 'Snowball',
},
isLoading: false,
isLoggedIn: true,
}
const loggedInUserWithRequestAlreadySent: User = {
...loggedInUser,
isLoading: true,
}
describe('REGISTRATION_REQUEST_SENT', () => {
it('indicates that the current user is loading', () => {
const action: RegistrationRequestSentAction = registrationRequestSent()
const newState: User = currentUser(undefined, action)
expect(newState.isLoading).toBe(true)
})
})
describe('REGISTRATION_REQUEST_SUCCEEDED', () => {
it('sets the current user and indicates that it is no longer loading and is logged in', () => {
const newUserAttributes: UserAttributes = {
firstName: 'Rick',
}
const action: RegistrationRequestSucceededAction = registrationRequestSucceeded(newUserAttributes)
const newState: User = currentUser(alreadyLoadingState, action)
const expectedNewState: User = {
attributes: newUserAttributes,
isLoading: false,
isLoggedIn: true,
}
expect(newState).toEqual(expectedNewState)
})
})
describe('REGISTRATION_REQUEST_FAILED', () => {
it('indicates that the current user is no longer loading', () => {
const action: RegistrationRequestFailedAction = registrationRequestFailed()
const newState: User = currentUser(alreadyLoadingState, action)
expect(newState.isLoading).toBe(false)
})
})
describe('VERIFY_TOKEN_REQUEST_SENT', () => {
it('indicates that the current user is loading', () => {
const action: VerifyTokenRequestSentAction = verifyTokenRequestSent()
const newState: User = currentUser(undefined, action)
expect(newState.isLoading).toBe(true)
})
})
describe('VERIFY_TOKEN_REQUEST_SUCCEEDED', () => {
it('sets the current user and indicates that it is no longer loading and is logged in', () => {
const newUserAttributes: UserAttributes = {
firstName: 'Morty',
}
const action: VerifyTokenRequestSucceededAction = verifyTokenRequestSucceeded(newUserAttributes)
const newState: User = currentUser(alreadyLoadingState, action)
const expectedNewState: User = {
attributes: newUserAttributes,
isLoading: false,
isLoggedIn: true,
}
expect(newState).toEqual(expectedNewState)
})
})
describe('VERIFY_TOKEN_REQUEST_FAILED', () => {
it('indicates that the current user is no longer loading and is not logged in', () => {
const loggedInState: User = {
...alreadyLoadingState,
isLoggedIn: true,
}
const action: VerifyTokenRequestFailedAction = verifyTokenRequestFailed()
const newState: User = currentUser(loggedInState, action)
expect(newState.isLoading).toBe(false)
expect(newState.isLoggedIn).toBe(false)
})
})
describe('SIGNIN_REQUEST_SENT', () => {
it('indicates that the current user is loading', () => {
const action: SignInRequestSentAction = signInRequestSent()
const newState: User = currentUser(undefined, action)
expect(newState.isLoading).toBe(true)
})
})
describe('SIGNIN_REQUEST_SUCCEEDED', () => {
it('sets the current user and indicates that it is no longer loading and is logged in', () => {
const newUserAttributes: UserAttributes = {
firstName: 'Rick',
}
const action: SignInRequestSucceededAction = signInRequestSucceeded(newUserAttributes)
const newState: User = currentUser(alreadyLoadingState, action)
const expectedNewState: User = {
attributes: newUserAttributes,
isLoading: false,
isLoggedIn: true,
}
expect(newState).toEqual(expectedNewState)
})
})
describe('SIGNIN_REQUEST_FAILED', () => {
it('indicates that the current user is no longer loading and is not logged in', () => {
const action: SignInRequestFailedAction = signInRequestFailed()
const newState: User = currentUser(alreadyLoadingState, action)
expect(newState.isLoading).toBe(false)
expect(newState.isLoggedIn).toBe(false)
})
})
describe('SIGNOUT_REQUEST_SENT', () => {
it('indicates that the current user is loading', () => {
const action: SignOutRequestSentAction = signOutRequestSent()
const newState: User = currentUser(loggedInUser, action)
expect(newState.isLoading).toBe(true)
})
})
describe('SIGNOUT_REQUEST_SUCCEEDED', () => {
it('indicates that the current user is not loading, is logged out, and has empty attributes', () => {
const action: SignOutRequestSucceededAction = signOutRequestSucceeded()
const newState: User = currentUser(loggedInUserWithRequestAlreadySent, action)
const expectedNewState: User = {
attributes: {
firstName: null,
},
isLoading: false,
isLoggedIn: false,
}
expect(newState).toEqual(expectedNewState)
})
})
describe('SIGNOUT_REQUEST_FAILED', () => {
it('indicates that the user is not loading but is stilled logged in', () => {
const action: SignOutRequestFailedAction = signOutRequestFailed()
const newState: User = currentUser(loggedInUserWithRequestAlreadySent, action)
const expectedNewState: User = {
...loggedInUserWithRequestAlreadySent,
isLoading: false,
}
expect(newState).toEqual(expectedNewState)
})
})
})

View File

@ -0,0 +1,71 @@
import {
User,
ReduxAction,
REGISTRATION_REQUEST_SENT,
REGISTRATION_REQUEST_SUCCEEDED,
REGISTRATION_REQUEST_FAILED,
VERIFY_TOKEN_REQUEST_SENT,
VERIFY_TOKEN_REQUEST_SUCCEEDED,
VERIFY_TOKEN_REQUEST_FAILED,
SIGNIN_REQUEST_SENT,
SIGNIN_REQUEST_SUCCEEDED,
SIGNIN_REQUEST_FAILED,
SIGNOUT_REQUEST_SENT,
SIGNOUT_REQUEST_SUCCEEDED,
SIGNOUT_REQUEST_FAILED,
} from '../../types'
import initialState from '../../initial-state'
const {
currentUser: initialUser,
} = initialState
const currentUser = (state: User = initialUser, action: ReduxAction): User => {
switch (action.type) {
case REGISTRATION_REQUEST_SENT:
case VERIFY_TOKEN_REQUEST_SENT:
case SIGNIN_REQUEST_SENT:
case SIGNOUT_REQUEST_SENT:
return {
...state,
isLoading: true,
}
case REGISTRATION_REQUEST_SUCCEEDED:
case VERIFY_TOKEN_REQUEST_SUCCEEDED:
case SIGNIN_REQUEST_SUCCEEDED:
const { userAttributes } = action.payload
return {
...state,
attributes: { ...userAttributes },
isLoading: false,
isLoggedIn: true,
}
case REGISTRATION_REQUEST_FAILED:
case VERIFY_TOKEN_REQUEST_FAILED:
case SIGNIN_REQUEST_FAILED:
return {
...state,
isLoading: false,
isLoggedIn: false,
}
case SIGNOUT_REQUEST_SUCCEEDED:
return {
...state,
attributes: {
...state.attributes,
firstName: null,
},
isLoading: false,
isLoggedIn: false,
}
case SIGNOUT_REQUEST_FAILED:
return {
...state,
isLoading: false,
}
default:
return state
}
}
export default currentUser

20
src/reducers/index.js Normal file
View File

@ -0,0 +1,20 @@
"use strict";
exports.__esModule = true;
var redux_1 = require("redux");
var current_user_1 = require("./current-user");
var reduxTokenAuthReducer = redux_1.combineReducers({
currentUser: current_user_1["default"]
});
exports["default"] = reduxTokenAuthReducer;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// An example of how the end-user will integrate this into their Redux store
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// import { combineReducers } from 'redux'
// import { reduxTokenAuthReducer } from 'redux-token-auth'
// import { myCustomReducer } from './my-custom-reducer'
//
// const rootReducer = combineReducers({
// reduxTokenAuth: reduxTokenAuthReducer,
// myCustomReducer,
// })
// Remember, they will have to user Redux Thunk when configuring their store

23
src/reducers/index.ts Normal file
View File

@ -0,0 +1,23 @@
import { combineReducers } from 'redux'
import currentUser from './current-user'
const reduxTokenAuthReducer = combineReducers({
currentUser,
})
export default reduxTokenAuthReducer
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// An example of how the end-user will integrate this into their Redux store
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// import { combineReducers } from 'redux'
// import { reduxTokenAuthReducer } from 'redux-token-auth'
// import { myCustomReducer } from './my-custom-reducer'
//
// const rootReducer = combineReducers({
// reduxTokenAuth: reduxTokenAuthReducer,
// myCustomReducer,
// })
// Remember, they will have to user Redux Thunk when configuring their store

32
src/services/auth.js Normal file
View File

@ -0,0 +1,32 @@
"use strict";
exports.__esModule = true;
var axios_1 = require("axios");
var authHeaderKeys = [
'access-token',
'token-type',
'client',
'expiry',
'uid',
];
exports.setAuthHeaders = function (headers) {
authHeaderKeys.forEach(function (key) {
axios_1["default"].defaults.headers.common[key] = headers[key];
});
};
// Will have to take a parameter from the package user to determine if this is for a browser or for React Native:
exports.persistAuthHeadersInLocalStorage = function (headers) {
authHeaderKeys.forEach(function (key) {
localStorage.setItem(key, headers[key]);
});
};
exports.deleteAuthHeaders = function () {
authHeaderKeys.forEach(function (key) {
delete axios_1["default"].defaults.headers.common[key];
});
};
// Will have to take a parameter from the package user to determine if this is for a browser or for React Native:
exports.deleteAuthHeadersFromLocalStorage = function () {
authHeaderKeys.forEach(function (key) {
localStorage.removeItem(key);
});
};

34
src/services/auth.test.ts Normal file
View File

@ -0,0 +1,34 @@
import axios from 'axios'
import { AuthHeaders } from '../types'
import {
setAuthHeaders,
deleteAuthHeaders,
} from './auth'
describe('auth service', () => {
const headers: AuthHeaders = {
'access-token': 'accessToken',
'token-type': 'tokenType',
client: 'client',
expiry: 'expiry',
uid: 'uid',
}
describe('setAuthHeaders', () => {
it('sets the appropriate auth headers on the global axios config', () => {
setAuthHeaders(headers)
Object.keys(headers).forEach((key: string) => {
expect(axios.defaults.headers.common[key]).toBe(headers[key])
})
})
})
describe('deleteAuthHeaders', () => {
it('deletes the appropriate auth headers from the global axios config', () => {
deleteAuthHeaders()
Object.keys(headers).forEach((key: string) => {
expect(axios.defaults.headers.common['access-token']).toBeUndefined()
})
})
})
})

36
src/services/auth.ts Normal file
View File

@ -0,0 +1,36 @@
import axios from 'axios'
import { AuthHeaders } from '../types'
const authHeaderKeys: Array<string> = [
'access-token',
'token-type',
'client',
'expiry',
'uid',
]
export const setAuthHeaders = (headers: AuthHeaders): void => {
authHeaderKeys.forEach((key: string) => {
axios.defaults.headers.common[key] = headers[key]
})
}
// Will have to take a parameter from the package user to determine if this is for a browser or for React Native:
export const persistAuthHeadersInLocalStorage = (headers: AuthHeaders): void => {
authHeaderKeys.forEach((key: string) => {
localStorage.setItem(key, headers[key])
})
}
export const deleteAuthHeaders = (): void => {
authHeaderKeys.forEach((key: string) => {
delete axios.defaults.headers.common[key]
})
}
// Will have to take a parameter from the package user to determine if this is for a browser or for React Native:
export const deleteAuthHeadersFromLocalStorage = (): void => {
authHeaderKeys.forEach((key: string) => {
localStorage.removeItem(key)
})
}

15
src/types.js Normal file
View File

@ -0,0 +1,15 @@
"use strict";
// Maybe make this the index.ts of a types directory so you can split things up
exports.__esModule = true;
exports.REGISTRATION_REQUEST_SENT = 'redux-token-auth/REGISTRATION_REQUEST_SENT';
exports.REGISTRATION_REQUEST_SUCCEEDED = 'redux-token-auth/REGISTRATION_REQUEST_SUCCEEDED';
exports.REGISTRATION_REQUEST_FAILED = 'redux-token-auth/REGISTRATION_REQUEST_FAILED';
exports.VERIFY_TOKEN_REQUEST_SENT = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SENT';
exports.VERIFY_TOKEN_REQUEST_SUCCEEDED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SUCCEEDED';
exports.VERIFY_TOKEN_REQUEST_FAILED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_FAILED';
exports.SIGNIN_REQUEST_SENT = 'redux-token-auth/SIGNIN_REQUEST_SENT';
exports.SIGNIN_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNIN_REQUEST_SUCCEEDED';
exports.SIGNIN_REQUEST_FAILED = 'redux-token-auth/SIGNIN_REQUEST_FAILED';
exports.SIGNOUT_REQUEST_SENT = 'redux-token-auth/SIGNOUT_REQUEST_SENT';
exports.SIGNOUT_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNOUT_REQUEST_SUCCEEDED';
exports.SIGNOUT_REQUEST_FAILED = 'redux-token-auth/SIGNOUT_REQUEST_FAILED';

156
src/types.ts Normal file
View File

@ -0,0 +1,156 @@
// Maybe make this the index.ts of a types directory so you can split things up
// This one in particular will be a little tough because we don't know what the package user's "User" model looks like:
export interface UserAttributes {}
export interface User {
readonly isLoggedIn: boolean
readonly isLoading: boolean
readonly attributes: UserAttributes
}
export interface ReduxState {
readonly currentUser: User
}
export interface AuthHeaders {
readonly 'access-token': string
readonly 'token-type': string
readonly client: string
readonly expiry: string
readonly uid: string
}
export interface AuthResponse {
readonly headers: AuthHeaders
}
export interface VerificationParams {
readonly uid: string
readonly client: string
readonly 'access-token': string
}
export type REGISTRATION_REQUEST_SENT = 'redux-token-auth/REGISTRATION_REQUEST_SENT'
export const REGISTRATION_REQUEST_SENT: REGISTRATION_REQUEST_SENT = 'redux-token-auth/REGISTRATION_REQUEST_SENT'
export type REGISTRATION_REQUEST_SUCCEEDED = 'redux-token-auth/REGISTRATION_REQUEST_SUCCEEDED'
export const REGISTRATION_REQUEST_SUCCEEDED: REGISTRATION_REQUEST_SUCCEEDED = 'redux-token-auth/REGISTRATION_REQUEST_SUCCEEDED'
export type REGISTRATION_REQUEST_FAILED = 'redux-token-auth/REGISTRATION_REQUEST_FAILED'
export const REGISTRATION_REQUEST_FAILED: REGISTRATION_REQUEST_FAILED = 'redux-token-auth/REGISTRATION_REQUEST_FAILED'
export type VERIFY_TOKEN_REQUEST_SENT = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SENT'
export const VERIFY_TOKEN_REQUEST_SENT: VERIFY_TOKEN_REQUEST_SENT = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SENT'
export type VERIFY_TOKEN_REQUEST_SUCCEEDED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SUCCEEDED'
export const VERIFY_TOKEN_REQUEST_SUCCEEDED: VERIFY_TOKEN_REQUEST_SUCCEEDED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_SUCCEEDED'
export type VERIFY_TOKEN_REQUEST_FAILED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_FAILED'
export const VERIFY_TOKEN_REQUEST_FAILED: VERIFY_TOKEN_REQUEST_FAILED = 'redux-token-auth/VERIFY_TOKEN_REQUEST_FAILED'
export type SIGNIN_REQUEST_SENT = 'redux-token-auth/SIGNIN_REQUEST_SENT'
export const SIGNIN_REQUEST_SENT: SIGNIN_REQUEST_SENT = 'redux-token-auth/SIGNIN_REQUEST_SENT'
export type SIGNIN_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNIN_REQUEST_SUCCEEDED'
export const SIGNIN_REQUEST_SUCCEEDED: SIGNIN_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNIN_REQUEST_SUCCEEDED'
export type SIGNIN_REQUEST_FAILED = 'redux-token-auth/SIGNIN_REQUEST_FAILED'
export const SIGNIN_REQUEST_FAILED: SIGNIN_REQUEST_FAILED = 'redux-token-auth/SIGNIN_REQUEST_FAILED'
export type SIGNOUT_REQUEST_SENT = 'redux-token-auth/SIGNOUT_REQUEST_SENT'
export const SIGNOUT_REQUEST_SENT: SIGNOUT_REQUEST_SENT = 'redux-token-auth/SIGNOUT_REQUEST_SENT'
export type SIGNOUT_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNOUT_REQUEST_SUCCEEDED'
export const SIGNOUT_REQUEST_SUCCEEDED: SIGNOUT_REQUEST_SUCCEEDED = 'redux-token-auth/SIGNOUT_REQUEST_SUCCEEDED'
export type SIGNOUT_REQUEST_FAILED = 'redux-token-auth/SIGNOUT_REQUEST_FAILED'
export const SIGNOUT_REQUEST_FAILED: SIGNOUT_REQUEST_FAILED = 'redux-token-auth/SIGNOUT_REQUEST_FAILED'
export interface UserRegistrationDetails {
readonly firstName: string
readonly email: string
readonly password: string
readonly passwordConfirmation: string
}
export interface UserSignInCredentials {
readonly email: string
readonly password: string
}
export interface UserSignOutCredentials {
readonly 'access-token': string
readonly client: string
readonly uid: string
}
export interface RegistrationRequestSentAction {
readonly type: REGISTRATION_REQUEST_SENT
}
export interface RegistrationRequestSucceededAction {
readonly type: REGISTRATION_REQUEST_SUCCEEDED
readonly payload: {
readonly userAttributes: UserAttributes
}
}
export interface RegistrationRequestFailedAction {
readonly type: REGISTRATION_REQUEST_FAILED
}
export interface VerifyTokenRequestSentAction {
readonly type: VERIFY_TOKEN_REQUEST_SENT
}
export interface VerifyTokenRequestSucceededAction {
readonly type: VERIFY_TOKEN_REQUEST_SUCCEEDED
readonly payload: {
readonly userAttributes: UserAttributes
}
}
export interface VerifyTokenRequestFailedAction {
readonly type: VERIFY_TOKEN_REQUEST_FAILED
}
export interface SignInRequestSentAction {
readonly type: SIGNIN_REQUEST_SENT
}
export interface SignInRequestSucceededAction {
readonly type: SIGNIN_REQUEST_SUCCEEDED
readonly payload: {
readonly userAttributes: UserAttributes
}
}
export interface SignInRequestFailedAction {
readonly type: SIGNIN_REQUEST_FAILED
}
export interface SignOutRequestSentAction {
readonly type: SIGNOUT_REQUEST_SENT
}
export interface SignOutRequestSucceededAction {
readonly type: SIGNOUT_REQUEST_SUCCEEDED
}
export interface SignOutRequestFailedAction {
readonly type: SIGNOUT_REQUEST_FAILED
}
export type ReduxAction = RegistrationRequestSentAction
| RegistrationRequestSucceededAction
| RegistrationRequestFailedAction
| VerifyTokenRequestSentAction
| VerifyTokenRequestSucceededAction
| VerifyTokenRequestFailedAction
| SignInRequestSentAction
| SignInRequestSucceededAction
| SignInRequestFailedAction
| SignOutRequestSentAction
| SignOutRequestSucceededAction
| SignOutRequestFailedAction

35
tsconfig.json Normal file
View File

@ -0,0 +1,35 @@
{
"compilerOptions": {
"outDir": "dist",
"module": "commonjs",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
},
"files": [
"src/index.ts"
],
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
],
"types": [
"typePatches"
]
}

99
tslint.json Normal file
View File

@ -0,0 +1,99 @@
{
"extends": ["tslint-react"],
"rules": {
"align": [
true,
"parameters",
"arguments",
"statements"
],
"ban": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": true,
"eofline": false,
"forin": true,
"indent": [ true, "spaces" ],
"interface-name": [true, "never-prefix"],
"jsdoc-format": true,
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"label-position": true,
"max-line-length": [ true, 120 ],
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": true,
"no-arg": true,
"no-bitwise": true,
"no-console": [
true,
"log",
"error",
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": false,
"no-unused-expression": true,
"no-use-before-declare": true,
"one-line": [
true,
"check-catch",
"check-else",
"check-open-brace",
"check-whitespace"
],
"quotemark": [true, "single", "jsx-double"],
"radix": true,
"semicolon": false,
"switch-default": true,
"trailing-comma": false,
"triple-equals": [ true, "allow-null-check" ],
"typedef": [
true,
"parameter",
"property-declaration"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-module",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
}
}

View File

@ -1,3 +0,0 @@
"use strict";
exports.__esModule = true;
exports.DO_THING = 'DO_THING';

View File

@ -1,6 +0,0 @@
export type DO_THING = 'DO_THING'
export const DO_THING: DO_THING = 'DO_THING'
export interface DoThingAction {
type: DO_THING
}