Skip to content

Commit d38f870

Browse files
authored
feat: support for dashboard APIs (#58)
* feat: support for dashboard APIs * finishes implementation * test fixes * updates CHANGELOG and version info * updates CHANGELOG.md * fixes
1 parent 15e8dd6 commit d38f870

File tree

7 files changed

+471
-23
lines changed

7 files changed

+471
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
99

10+
## [2.2.0] - 2023-02-21
11+
12+
- Adds support for Dashboard recipe
13+
1014
## [2.1.0] - 2022-11-07
1115

1216
- Updates dependencies as per: https://github.com/supertokens/supertokens-core/issues/525

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ plugins {
22
id 'java-library'
33
}
44

5-
version = "2.1.0"
5+
version = "2.2.0"
66

77
repositories {
88
mavenCentral()

pluginInterfaceSupported.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"_comment": "contains a list of plugin interfaces branch names that this core supports",
33
"versions": [
4-
"2.19"
4+
"2.20"
55
]
66
}

src/main/java/io/supertokens/storage/postgresql/Start.java

Lines changed: 179 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
import io.supertokens.pluginInterface.RECIPE_ID;
2525
import io.supertokens.pluginInterface.STORAGE_TYPE;
2626
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
27+
import io.supertokens.pluginInterface.dashboard.DashboardSessionInfo;
28+
import io.supertokens.pluginInterface.dashboard.DashboardUser;
29+
import io.supertokens.pluginInterface.dashboard.exceptions.UserIdNotFoundException;
30+
import io.supertokens.pluginInterface.dashboard.sqlStorage.DashboardSQLStorage;
2731
import io.supertokens.pluginInterface.emailpassword.PasswordResetTokenInfo;
2832
import io.supertokens.pluginInterface.emailpassword.UserInfo;
2933
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
@@ -84,7 +88,8 @@
8488

8589
public class Start
8690
implements SessionSQLStorage, EmailPasswordSQLStorage, EmailVerificationSQLStorage, ThirdPartySQLStorage,
87-
JWTRecipeSQLStorage, PasswordlessSQLStorage, UserMetadataSQLStorage, UserRolesSQLStorage, UserIdMappingStorage {
91+
JWTRecipeSQLStorage, PasswordlessSQLStorage, UserMetadataSQLStorage, UserRolesSQLStorage, UserIdMappingStorage,
92+
DashboardSQLStorage {
8893

8994
private static final Object appenderLock = new Object();
9095
public static boolean silent = false;
@@ -225,7 +230,8 @@ public <T> T startTransaction(TransactionLogic<T> logic, TransactionIsolationLev
225230
} catch (InterruptedException ignored) {
226231
}
227232
ProcessState.getInstance(this).addState(ProcessState.PROCESS_STATE.DEADLOCK_FOUND, e);
228-
// this because deadlocks are not necessarily a result of faulty logic. They can happen
233+
// this because deadlocks are not necessarily a result of faulty logic. They can
234+
// happen
229235
continue;
230236
}
231237
if (e instanceof StorageQueryException) {
@@ -247,21 +253,21 @@ private <T> T startTransactionHelper(TransactionLogic<T> logic, TransactionIsola
247253
defaultTransactionIsolation = con.getTransactionIsolation();
248254
int libIsolationLevel = Connection.TRANSACTION_SERIALIZABLE;
249255
switch (isolationLevel) {
250-
case SERIALIZABLE:
251-
libIsolationLevel = Connection.TRANSACTION_SERIALIZABLE;
252-
break;
253-
case REPEATABLE_READ:
254-
libIsolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
255-
break;
256-
case READ_COMMITTED:
257-
libIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
258-
break;
259-
case READ_UNCOMMITTED:
260-
libIsolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
261-
break;
262-
case NONE:
263-
libIsolationLevel = Connection.TRANSACTION_NONE;
264-
break;
256+
case SERIALIZABLE:
257+
libIsolationLevel = Connection.TRANSACTION_SERIALIZABLE;
258+
break;
259+
case REPEATABLE_READ:
260+
libIsolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
261+
break;
262+
case READ_COMMITTED:
263+
libIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
264+
break;
265+
case READ_UNCOMMITTED:
266+
libIsolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
267+
break;
268+
case NONE:
269+
libIsolationLevel = Connection.TRANSACTION_NONE;
270+
break;
265271
}
266272
con.setTransactionIsolation(libIsolationLevel);
267273
con.setAutoCommit(false);
@@ -1813,4 +1819,160 @@ public HashMap<String, String> getUserIdMappingForSuperTokensIds(ArrayList<Strin
18131819
throw new StorageQueryException(e);
18141820
}
18151821
}
1822+
1823+
@Override
1824+
public void createNewDashboardUser(DashboardUser userInfo)
1825+
throws StorageQueryException, io.supertokens.pluginInterface.dashboard.exceptions.DuplicateUserIdException,
1826+
io.supertokens.pluginInterface.dashboard.exceptions.DuplicateEmailException {
1827+
try {
1828+
DashboardQueries.createDashboardUser(this, userInfo.userId, userInfo.email, userInfo.passwordHash,
1829+
userInfo.timeJoined);
1830+
} catch (SQLException e) {
1831+
if (e instanceof PSQLException) {
1832+
PostgreSQLConfig config = Config.getConfig(this);
1833+
ServerErrorMessage serverErrorMessage = ((PSQLException) e).getServerErrorMessage();
1834+
1835+
if (isPrimaryKeyError(serverErrorMessage, config.getDashboardUsersTable())) {
1836+
throw new io.supertokens.pluginInterface.dashboard.exceptions.DuplicateUserIdException();
1837+
}
1838+
if (isUniqueConstraintError(serverErrorMessage, config.getDashboardUsersTable(),
1839+
"email")) {
1840+
throw new io.supertokens.pluginInterface.dashboard.exceptions.DuplicateEmailException();
1841+
1842+
}
1843+
}
1844+
throw new StorageQueryException(e);
1845+
}
1846+
1847+
}
1848+
1849+
@Override
1850+
public DashboardUser getDashboardUserByEmail(String email) throws StorageQueryException {
1851+
try {
1852+
return DashboardQueries.getDashboardUserByEmail(this, email);
1853+
} catch (SQLException e) {
1854+
throw new StorageQueryException(e);
1855+
}
1856+
}
1857+
1858+
@Override
1859+
public DashboardUser getDashboardUserByUserId(String userId) throws StorageQueryException {
1860+
try {
1861+
return DashboardQueries.getDashboardUserByUserId(this, userId);
1862+
} catch (SQLException e) {
1863+
throw new StorageQueryException(e);
1864+
}
1865+
}
1866+
1867+
@Override
1868+
public DashboardUser[] getAllDashboardUsers() throws StorageQueryException {
1869+
try {
1870+
return DashboardQueries.getAllDashBoardUsers(this);
1871+
} catch (SQLException e) {
1872+
throw new StorageQueryException(e);
1873+
}
1874+
}
1875+
1876+
@Override
1877+
public boolean deleteDashboardUserWithUserId(String userId) throws StorageQueryException {
1878+
try {
1879+
return DashboardQueries.deleteDashboardUserWithUserId(this, userId);
1880+
} catch (SQLException e) {
1881+
throw new StorageQueryException(e);
1882+
}
1883+
}
1884+
1885+
@Override
1886+
public void createNewDashboardUserSession(String userId, String sessionId, long timeCreated, long expiry)
1887+
throws StorageQueryException, UserIdNotFoundException {
1888+
try {
1889+
DashboardQueries.createDashboardSession(this, userId, sessionId, timeCreated, expiry);
1890+
} catch (SQLException e) {
1891+
if (e instanceof PSQLException) {
1892+
ServerErrorMessage serverMessage = ((PSQLException) e).getServerErrorMessage();
1893+
1894+
if (isForeignKeyConstraintError(serverMessage,
1895+
Config.getConfig(this).getDashboardSessionsTable(), "user_id")) {
1896+
throw new UserIdNotFoundException();
1897+
}
1898+
}
1899+
throw new StorageQueryException(e);
1900+
}
1901+
}
1902+
1903+
@Override
1904+
public DashboardSessionInfo[] getAllSessionsForUserId(String userId) throws StorageQueryException {
1905+
try {
1906+
return DashboardQueries.getAllSessionsForUserId(this, userId);
1907+
} catch (SQLException e) {
1908+
throw new StorageQueryException(e);
1909+
}
1910+
}
1911+
1912+
@Override
1913+
public DashboardSessionInfo getSessionInfoWithSessionId(String sessionId) throws StorageQueryException {
1914+
try {
1915+
return DashboardQueries.getSessionInfoWithSessionId(this, sessionId);
1916+
} catch (SQLException e) {
1917+
throw new StorageQueryException(e);
1918+
}
1919+
}
1920+
1921+
@Override
1922+
public boolean revokeSessionWithSessionId(String sessionId) throws StorageQueryException {
1923+
try {
1924+
return DashboardQueries.deleteDashboardUserSessionWithSessionId(this, sessionId);
1925+
} catch (SQLException e) {
1926+
throw new StorageQueryException(e);
1927+
}
1928+
}
1929+
1930+
@Override
1931+
public void revokeExpiredSessions() throws StorageQueryException {
1932+
try {
1933+
DashboardQueries.deleteExpiredSessions(this);
1934+
} catch (SQLException e) {
1935+
throw new StorageQueryException(e);
1936+
}
1937+
1938+
}
1939+
1940+
@Override
1941+
public void updateDashboardUsersEmailWithUserId_Transaction(TransactionConnection con, String userId,
1942+
String newEmail) throws StorageQueryException,
1943+
io.supertokens.pluginInterface.dashboard.exceptions.DuplicateEmailException, UserIdNotFoundException {
1944+
Connection sqlCon = (Connection) con.getConnection();
1945+
try {
1946+
if (!DashboardQueries.updateDashboardUsersEmailWithUserId_Transaction(this, sqlCon, userId, newEmail)) {
1947+
throw new UserIdNotFoundException();
1948+
}
1949+
} catch (SQLException e) {
1950+
if (e instanceof PSQLException) {
1951+
PostgreSQLConfig config = Config.getConfig(this);
1952+
ServerErrorMessage serverErrorMessage = ((PSQLException) e).getServerErrorMessage();
1953+
1954+
if (isUniqueConstraintError(serverErrorMessage, config.getDashboardUsersTable(),
1955+
"email")) {
1956+
throw new io.supertokens.pluginInterface.dashboard.exceptions.DuplicateEmailException();
1957+
}
1958+
}
1959+
throw new StorageQueryException(e);
1960+
}
1961+
1962+
}
1963+
1964+
@Override
1965+
public void updateDashboardUsersPasswordWithUserId_Transaction(TransactionConnection con, String userId,
1966+
String newPassword) throws StorageQueryException, UserIdNotFoundException {
1967+
Connection sqlCon = (Connection) con.getConnection();
1968+
try {
1969+
if (!DashboardQueries.updateDashboardUsersPasswordWithUserId_Transaction(this, sqlCon, userId,
1970+
newPassword)) {
1971+
throw new UserIdNotFoundException();
1972+
}
1973+
} catch (SQLException e) {
1974+
throw new StorageQueryException(e);
1975+
}
1976+
1977+
}
18161978
}

src/main/java/io/supertokens/storage/postgresql/config/PostgreSQLConfig.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,14 @@ public String getUserIdMappingTable() {
297297
return addSchemaAndPrefixToTableName("userid_mapping");
298298
}
299299

300+
public String getDashboardUsersTable() {
301+
return addSchemaAndPrefixToTableName("dashboard_users");
302+
}
303+
304+
public String getDashboardSessionsTable() {
305+
return addSchemaAndPrefixToTableName("dashboard_user_sessions");
306+
}
307+
300308
private String addSchemaAndPrefixToTableName(String tableName) {
301309
String name = tableName;
302310
if (!postgresql_table_names_prefix.trim().equals("")) {

0 commit comments

Comments
 (0)