Jamespot
This guide explains how to set up Single Sign-On (SSO) between SmartLink and Jamespot using SAML 2.0.
Prerequisites
- Jamespot Pro or Enterprise subscription
- Administrative access to Jamespot
- Verified email domain
- Application configured in SmartLink with SAML2
Note: SSO is available with Jamespot Pro and Enterprise subscriptions.
Configuration in SmartLink
1. Create the application
- Log in to SmartLink as an administrator
- Go to Applications → Add
- Create a new application:
- Name: Jamespot
- URL:
https://[your-organization].jamespot.com - Description: French collaborative digital workplace
- Icon: Choose the Jamespot icon
2. Configure SAML2
- In the Authentication tab
- Select SAML2
- Configure the following parameters:
- Entity ID:
[appid] - ACS URL:
https://[your-organization].jamespot.com/saml/acs - Format NameID:
emailAddress - App ID:
[appid](automatically generated unique identifier)
- Entity ID:
3. Retrieve metadata
Note the following URLs:
- IdP Metadata:
https://[your-smartlink].link.vaultys.org/api/saml2/[appid]/metadata - SSO URL:
https://[your-smartlink].link.vaultys.org/api/saml2/[appid]/sso - SLO URL:
https://[your-smartlink].link.vaultys.org/api/saml2/[appid]/slo - Entity ID:
https://[your-smartlink].link.vaultys.org/[appid] - X.509 Certificate: Download from SmartLink
Configuration in Jamespot
1. Access SSO settings
- Log in to Jamespot as an administrator
- Go to Administration → General Settings → Authentication
- Click on Configure SAML SSO
2. Identity provider configuration
Configure the SAML parameters:
- IdP Entity ID:
[appid] - SSO Login URL:
https://[your-smartlink].link.vaultys.org/api/saml2/[appid]/sso - SSO Logout URL:
https://[your-smartlink].link.vaultys.org/api/saml2/[appid]/slo - IdP Public Certificate: Paste the X.509 certificate from SmartLink
- Binding:
HTTP-POST
3. Attribute configuration
| Jamespot Attribute | SAML Attribute | Required |
|---|---|---|
email | ✅ | |
| First Name | givenName | ✅ |
| Last Name | surname | ✅ |
| Full Name | displayName | ❌ |
| Service | department | ❌ |
| Job Title | jobTitle | ❌ |
| Phone | telephoneNumber | ❌ |
| Mobile | mobile | ❌ |
| Location | location | ❌ |
Spaces and Groups Configuration
Spaces structure
spaces:
- name: "Corporate Space"
type: "organization"
access: "all_users"
features:
- news_feed
- corporate_directory
- org_chart
- announcements
- name: "Projects Space"
type: "project"
access: "members_only"
features:
- task_management
- document_sharing
- team_calendar
- wikis
- name: "Innovation Space"
type: "community"
access: "open"
features:
- idea_box
- innovation_challenges
- polls
- forums
Group synchronization
{
"group_mapping": {
"smartlink-admins": {
"jamespot_role": "administrator",
"permissions": ["manage_platform", "manage_users", "manage_content"]
},
"smartlink-managers": {
"jamespot_role": "space_manager",
"permissions": ["create_spaces", "manage_members", "moderate_content"]
},
"smartlink-employees": {
"jamespot_role": "contributor",
"permissions": ["create_content", "participate", "collaborate"]
},
"smartlink-external": {
"jamespot_role": "guest",
"permissions": ["view_public", "limited_interaction"]
}
}
}
Modules and Features
Enterprise Social Network
social_features:
wall:
enabled: true
moderation: automatic
content_types:
- posts
- articles
- events
- polls
- ideas
interactions:
likes: true
comments: true
shares: true
mentions: true
hashtags: true
gamification:
points: true
badges: true
leaderboard: true
challenges: true
Document Management
{
"document_management": {
"storage_quota": "100GB",
"version_control": true,
"co_editing": {
"enabled": true,
"office_suite": "onlyoffice"
},
"permissions": {
"folder_level": true,
"file_level": true,
"sharing_control": true
},
"search": {
"full_text": true,
"ocr": true,
"metadata": true
}
}
}
Business Applications
business_apps:
- name: "Project Management"
features:
- gantt_charts
- kanban_boards
- time_tracking
- resource_planning
- name: "Knowledge Base"
features:
- wikis
- faqs
- tutorials
- best_practices
- name: "Innovation"
features:
- idea_management
- innovation_campaigns
- voting_system
- roi_tracking
Jamespot API
Client API with SSO
const axios = require('axios');
class JamespotAPI {
constructor(config) {
this.baseUrl = `https://${config.domain}.jamespot.com/api/v3`;
this.apiKey = config.apiKey;
this.headers = {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
};
}
async getUserBySSOEmail(email) {
const response = await axios.get(`${this.baseUrl}/users`, {
params: { email },
headers: this.headers
});
return response.data;
}
async createSpace(spaceData) {
const response = await axios.post(`${this.baseUrl}/spaces`, {
name: spaceData.name,
type: spaceData.type,
description: spaceData.description,
members: spaceData.members,
settings: {
visibility: spaceData.visibility || 'private',
moderation: spaceData.moderation || true
}
}, { headers: this.headers });
return response.data;
}
async publishContent(spaceId, content) {
const response = await axios.post(`${this.baseUrl}/spaces/${spaceId}/posts`, {
title: content.title,
body: content.body,
type: content.type,
tags: content.tags,
attachments: content.attachments
}, { headers: this.headers });
return response.data;
}
}
Webhooks
// Endpoint for Jamespot webhooks
app.post('/webhook/jamespot', async (req, res) => {
const { event, payload } = req.body;
const signature = req.headers['x-jamespot-signature'];
// Verify the signature
if (!verifySignature(signature, req.body, process.env.JAMESPOT_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
switch(event) {
case 'user.login':
await trackUserLogin(payload);
break;
case 'content.created':
await processNewContent(payload);
break;
case 'space.member.added':
await notifyNewMember(payload);
break;
case 'task.completed':
await updateProjectStatus(payload);
break;
}
res.status(200).json({ received: true });
});
Configuration Testing
1. Connection Test
- Log out of Jamespot
- Go to
https://[your-organization].jamespot.com - Click on Login with SSO
- Authenticate via SmartLink
- Verify access to your spaces
2. API Test
# Get user information
curl -X GET "https://[your-organization].jamespot.com/api/v3/me" \
-H "Authorization: Bearer YOUR_API_KEY"
3. Mobile Test
Available Jamespot applications:
- Jamespot Mobile (iOS/Android)
- Full SSO support
- Push notifications
Troubleshooting
Error "SAML response is not valid"
Issue: The SAML response is rejected
Solution:
- Verify that the Entity ID is
[appid] - Check the X.509 certificate (PEM format)
- Ensure the ACS URL is correct
- Check the logs: Administration → System Logs
Groups not synchronized
Issue: Jamespot roles do not match SmartLink groups
Solution:
<!-- SAML assertion for groups -->
<saml:Attribute Name="memberOf">
<saml:AttributeValue>CN=jamespot-admins,OU=Groups,DC=example,DC=com</saml:AttributeValue>
<saml:AttributeValue>CN=jamespot-users,OU=Groups,DC=example,DC=com</saml:AttributeValue>
</saml:Attribute>
Session issue
Issue: Session expires too quickly
Solution:
- Increase session duration in Jamespot
- Check session configuration in SmartLink
- Align timeout settings on both sides
Security
Recommended Configuration
{
"security_settings": {
"enforce_sso": true,
"session_timeout": "8h",
"concurrent_sessions": false,
"ip_restrictions": {
"enabled": false,
"whitelist": []
},
"content_security": {
"moderation": "ai_assisted",
"dlp": true,
"watermarking": false
},
"audit": {
"enabled": true,
"retention": "2y",
"export_format": "csv"
}
}
}
GDPR Compliance
Jamespot is GDPR compliant with:
- Data hosting in France
- Right to erasure
- Data portability
- Records of processing activities
- Designated Data Protection Officer (DPO)
User Migration
Migration Script
import csv
import requests
from datetime import datetime
class JamespotMigration:
def __init__(self, domain, api_key):
self.domain = domain
self.api_key = api_key
self.base_url = f"https://{domain}.jamespot.com/api/v3"
def migrate_to_sso(self, users_csv):
"""Migrates users to SSO"""
results = []
with open(users_csv, 'r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for user in reader:
try:
# Enable SSO for the user
response = requests.patch(
f"{self.base_url}/users/{user['id']}",
headers={'Authorization': f'Bearer {self.api_key}'},
json={
'authentication_method': 'sso',
'sso_email': user['email']
}
)
if response.status_code == 200:
results.append({
'email': user['email'],
'status': 'success',
'timestamp': datetime.now()
})
# Send notification email
self.send_notification(user['email'])
else:
results.append({
'email': user['email'],
'status': 'failed',
'error': response.text
})
except Exception as e:
results.append({
'email': user['email'],
'status': 'error',
'error': str(e)
})
return results
def send_notification(self, email):
"""Sends a notification email for SSO migration"""
# Implement email sending
pass