fastcomments-sdk
Version:
FastComments API Client - A SDK for interacting with the FastComments API
223 lines • 12.5 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_test_1 = require("node:test");
const node_assert_1 = __importDefault(require("node:assert"));
const crypto_1 = __importDefault(require("crypto"));
const sso_1 = require("../sso");
const env_1 = require("./env");
(0, node_test_1.describe)('FastComments SSO', () => {
const mockSecureUser = {
id: 'test-user-123',
email: 'test@example.com',
username: 'testuser',
displayName: 'Test User',
avatar: 'https://example.com/avatar.jpg',
optedInNotifications: true,
displayLabel: 'Test User',
websiteUrl: 'https://example.com',
groupIds: ['group1', 'group2'],
isAdmin: false,
isModerator: true,
isProfileActivityPrivate: true
};
const mockSimpleUser = {
id: 'simple-user-123',
email: 'simple@example.com',
username: 'simpleuser',
displayName: 'Simple User',
avatar: 'https://example.com/simple-avatar.jpg',
optedInNotifications: false,
displayLabel: 'Regular User',
websiteUrl: 'https://simple.example.com',
locale: 'en_us'
};
const mockConfig = {
loginURL: '/login',
logoutURL: '/logout',
loginCallback: () => console.log('Login callback'),
logoutCallback: () => console.log('Logout callback')
};
(0, node_test_1.describe)('SecureSSOPayloadBuilder', () => {
(0, node_test_1.it)('should create a valid secure SSO payload', () => {
const builder = new sso_1.SecureSSOPayloadBuilder(env_1.API_KEY, mockSecureUser);
const payload = builder.getPayload();
node_assert_1.default.ok(payload);
node_assert_1.default.ok(payload.userDataJSONBase64);
node_assert_1.default.ok(payload.verificationHash);
node_assert_1.default.ok(payload.timestamp);
node_assert_1.default.strictEqual(typeof payload.timestamp, 'number');
});
(0, node_test_1.it)('should create a valid HMAC-SHA256 hash', () => {
const builder = new sso_1.SecureSSOPayloadBuilder(env_1.API_KEY, mockSecureUser);
const payload = builder.getPayload();
// Verify the hash manually
const hmac = crypto_1.default.createHmac('sha256', env_1.API_KEY);
hmac.update(payload.timestamp + payload.userDataJSONBase64);
const expectedHash = hmac.digest('hex');
node_assert_1.default.strictEqual(payload.verificationHash, expectedHash);
});
(0, node_test_1.it)('should encode user data properly in base64', () => {
const builder = new sso_1.SecureSSOPayloadBuilder(env_1.API_KEY, mockSecureUser);
const payload = builder.getPayload();
const decodedData = JSON.parse(Buffer.from(payload.userDataJSONBase64, 'base64').toString('utf8'));
node_assert_1.default.deepStrictEqual(decodedData, mockSecureUser);
});
(0, node_test_1.it)('should produce JSON output', () => {
const builder = new sso_1.SecureSSOPayloadBuilder(env_1.API_KEY, mockSecureUser);
const jsonOutput = builder.toJSON();
node_assert_1.default.doesNotThrow(() => JSON.parse(jsonOutput));
const parsed = JSON.parse(jsonOutput);
node_assert_1.default.ok(parsed.userDataJSONBase64);
node_assert_1.default.ok(parsed.verificationHash);
node_assert_1.default.ok(parsed.timestamp);
});
});
(0, node_test_1.describe)('FastCommentsSSO - Secure SSO', () => {
(0, node_test_1.it)('should create secure SSO using factory method', () => {
const sso = sso_1.FastCommentsSSO.createSecure(env_1.API_KEY, mockSecureUser, mockConfig);
node_assert_1.default.ok(sso);
node_assert_1.default.strictEqual(sso.isSecure(), true);
node_assert_1.default.strictEqual(sso.isSimple(), false);
});
(0, node_test_1.it)('should prepare secure SSO for transmission', () => {
const sso = sso_1.FastCommentsSSO.createSecure(env_1.API_KEY, mockSecureUser, mockConfig);
const config = sso.prepareToSend();
node_assert_1.default.ok(config);
node_assert_1.default.ok(config.userDataJSONBase64);
node_assert_1.default.ok(config.verificationHash);
node_assert_1.default.ok(config.timestamp);
node_assert_1.default.strictEqual(config.loginURL, mockConfig.loginURL);
node_assert_1.default.strictEqual(config.logoutURL, mockConfig.logoutURL);
});
(0, node_test_1.it)('should throw error when calling createToken on secure SSO', () => {
const sso = sso_1.FastCommentsSSO.createSecure(env_1.API_KEY, mockSecureUser);
node_assert_1.default.throws(() => sso.createToken(), /createToken\(\) can only be called on simple SSO instances/);
});
(0, node_test_1.it)('should return secure config from getToken', () => {
const sso = sso_1.FastCommentsSSO.createSecure(env_1.API_KEY, mockSecureUser, mockConfig);
const token = sso.getToken();
node_assert_1.default.strictEqual(typeof token, 'object');
if (typeof token === 'object') {
node_assert_1.default.ok('userDataJSONBase64' in token);
node_assert_1.default.ok('verificationHash' in token);
node_assert_1.default.ok('timestamp' in token);
}
});
});
(0, node_test_1.describe)('FastCommentsSSO - Simple SSO', () => {
(0, node_test_1.it)('should create simple SSO using factory method', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
node_assert_1.default.ok(sso);
node_assert_1.default.strictEqual(sso.isSimple(), true);
node_assert_1.default.strictEqual(sso.isSecure(), false);
});
(0, node_test_1.it)('should create token for simple SSO', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
const token = sso.createToken();
node_assert_1.default.strictEqual(typeof token, 'string');
const parsed = JSON.parse(token);
node_assert_1.default.strictEqual(parsed.email, mockSimpleUser.email);
node_assert_1.default.strictEqual(parsed.username, mockSimpleUser.username);
node_assert_1.default.strictEqual(parsed.loginURL, mockConfig.loginURL);
node_assert_1.default.strictEqual(parsed.logoutURL, mockConfig.logoutURL);
});
(0, node_test_1.it)('should cache tokens', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
const token1 = sso.createToken();
const token2 = sso.createToken();
node_assert_1.default.strictEqual(token1, token2); // Should be the same cached instance
});
(0, node_test_1.it)('should reset cached token', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
const token1 = sso.createToken();
sso.resetToken();
sso.updateConfig({ loginURL: '/new-login' });
const token2 = sso.createToken();
node_assert_1.default.notStrictEqual(token1, token2); // Should be different after config change
});
(0, node_test_1.it)('should throw error when calling prepareToSend on simple SSO', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser);
node_assert_1.default.throws(() => sso.prepareToSend(), /prepareToSend\(\) can only be called on secure SSO instances/);
});
(0, node_test_1.it)('should return token string from getToken', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
const token = sso.getToken();
node_assert_1.default.strictEqual(typeof token, 'string');
if (typeof token === 'string') {
const parsed = JSON.parse(token);
node_assert_1.default.strictEqual(parsed.email, mockSimpleUser.email);
}
});
});
(0, node_test_1.describe)('FastCommentsSSO - Configuration Management', () => {
(0, node_test_1.it)('should update configuration', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
const newConfig = { loginURL: '/new-login', logoutURL: '/new-logout' };
sso.updateConfig(newConfig);
const config = sso.getConfig();
node_assert_1.default.strictEqual(config.loginURL, '/new-login');
node_assert_1.default.strictEqual(config.logoutURL, '/new-logout');
node_assert_1.default.strictEqual(config.loginCallback, mockConfig.loginCallback); // Should preserve existing
});
(0, node_test_1.it)('should return copy of configuration', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, mockConfig);
const config = sso.getConfig();
config.loginURL = 'modified';
const config2 = sso.getConfig();
node_assert_1.default.strictEqual(config2.loginURL, mockConfig.loginURL); // Should not be modified
});
});
(0, node_test_1.describe)('FastCommentsSSO - Constructor Overloads', () => {
(0, node_test_1.it)('should accept SecureSSOPayload in constructor', () => {
const builder = new sso_1.SecureSSOPayloadBuilder(env_1.API_KEY, mockSecureUser);
const payload = builder.getPayload();
const sso = new sso_1.FastCommentsSSO(payload, mockConfig);
node_assert_1.default.strictEqual(sso.isSecure(), true);
node_assert_1.default.ok(sso.prepareToSend());
});
(0, node_test_1.it)('should accept SimpleSSOUserData in constructor', () => {
const sso = new sso_1.FastCommentsSSO(mockSimpleUser, mockConfig);
node_assert_1.default.strictEqual(sso.isSimple(), true);
node_assert_1.default.ok(sso.createToken());
});
(0, node_test_1.it)('should work without config parameter', () => {
const sso = new sso_1.FastCommentsSSO(mockSimpleUser);
node_assert_1.default.strictEqual(sso.isSimple(), true);
const token = sso.createToken();
const parsed = JSON.parse(token);
node_assert_1.default.strictEqual(parsed.email, mockSimpleUser.email);
});
});
(0, node_test_1.describe)('FastCommentsSSO - Edge Cases', () => {
(0, node_test_1.it)('should handle user data with missing optional fields', () => {
const minimalUser = {
id: 'minimal-user',
email: 'minimal@example.com',
username: 'minimal'
};
const sso = sso_1.FastCommentsSSO.createSecure(env_1.API_KEY, minimalUser);
const config = sso.prepareToSend();
node_assert_1.default.ok(config.userDataJSONBase64);
const decodedData = JSON.parse(Buffer.from(config.userDataJSONBase64, 'base64').toString('utf8'));
node_assert_1.default.strictEqual(decodedData.id, 'minimal-user');
node_assert_1.default.strictEqual(decodedData.email, 'minimal@example.com');
node_assert_1.default.strictEqual(decodedData.username, 'minimal');
});
(0, node_test_1.it)('should handle empty config', () => {
const sso = sso_1.FastCommentsSSO.createSimple(mockSimpleUser, {});
const token = sso.createToken();
node_assert_1.default.strictEqual(typeof token, 'string');
const parsed = JSON.parse(token);
node_assert_1.default.strictEqual(parsed.email, mockSimpleUser.email);
});
(0, node_test_1.it)('should throw error when getToken called with no data', () => {
// This shouldn't be possible with TypeScript, but let's test the runtime check
const sso = new sso_1.FastCommentsSSO();
node_assert_1.default.throws(() => sso.getToken(), /No SSO data available/);
});
});
});
//# sourceMappingURL=sso.test.js.map